1
/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
7
#include "str-sanitize.h"
10
#include "test-common.h"
11
#include "http-transfer.h"
15
struct http_transfer_chunked_input_test {
20
/* Valid transfer_chunked input tests */
21
static struct http_transfer_chunked_input_test
22
valid_transfer_chunked_input_tests[] = {
24
"This is a simple test payload."
29
"This is a simple test payload."
32
"This is a longer test payload..."
35
"...spread over two separate chunks."
40
"This is a longer test payload..."
41
"...spread over two separate chunks."
44
"This is an even longer test payload..."
47
"...spread over three separate chunks..."
50
"...and also includes a trailer."
53
"Checksum: adgfef3fdaf3daf3dfaf3ff3fdag\r\n"
54
"X-Dovecot: Whatever\r\n"
57
"This is an even longer test payload..."
58
"...spread over three separate chunks..."
59
"...and also includes a trailer."
62
"This is an even longer test payload..."
65
"...spread over three separate chunks..."
68
"...and also includes a trailer."
71
"Checksum: adgfef3fdaf3daf3dfaf3ff3fdag\n"
72
"X-Dovecot: Whatever\n"
75
"This is an even longer test payload..."
76
"...spread over three separate chunks..."
77
"...and also includes a trailer."
81
static unsigned int valid_transfer_chunked_input_test_count =
82
N_ELEMENTS(valid_transfer_chunked_input_tests);
84
static void test_http_transfer_chunked_input_valid(void)
86
struct istream *input, *chunked;
87
struct ostream *output;
88
buffer_t *payload_buffer;
91
payload_buffer = buffer_create_dynamic(default_pool, 1024);
93
for (i = 0; i < valid_transfer_chunked_input_test_count; i++) T_BEGIN {
94
const char *in, *out, *stream_out;
96
in = valid_transfer_chunked_input_tests[i].in;
97
out = valid_transfer_chunked_input_tests[i].out;
99
test_begin(t_strdup_printf("http transfer_chunked input valid [%d]", i));
101
input = i_stream_create_from_data(in, strlen(in));
102
chunked = http_transfer_chunked_istream_create(input, 0);
104
buffer_set_used_size(payload_buffer, 0);
105
output = o_stream_create_buffer(payload_buffer);
106
test_out("payload read", o_stream_send_istream(output, chunked) > 0
107
&& chunked->stream_errno == 0);
108
o_stream_destroy(&output);
109
stream_out = str_c(payload_buffer);
111
test_out(t_strdup_printf("response->payload = %s",
112
str_sanitize(stream_out, 80)),
113
strcmp(stream_out, out) == 0);
117
buffer_free(&payload_buffer);
120
/* Invalid transfer_chunked input tests */
122
invalid_transfer_chunked_input_tests[] = {
125
"This is a simple test payload."
131
"This is a simple test payload."
137
"This is a longer test payload..."
140
"...spread over two separate chunks."
146
"This is a longer test payload..."
149
"...spread over two separate chunks."
152
// invalid last chunk
154
"This is a longer test payload..."
157
"...spread over two separate chunks."
163
"This is an even longer test payload..."
166
"...spread over three separate chunks..."
169
"...and also includes a trailer."
172
"Checksum adgfef3fdaf3daf3dfaf3ff3fdag\r\n"
176
static unsigned int invalid_transfer_chunked_input_test_count =
177
N_ELEMENTS(invalid_transfer_chunked_input_tests);
179
static void test_http_transfer_chunked_input_invalid(void)
181
struct istream *input, *chunked;
182
struct ostream *output;
183
buffer_t *payload_buffer;
186
payload_buffer = buffer_create_dynamic(default_pool, 1024);
188
for (i = 0; i < invalid_transfer_chunked_input_test_count; i++) T_BEGIN {
191
in = invalid_transfer_chunked_input_tests[i];
193
test_begin(t_strdup_printf("http transfer_chunked input invalid [%d]", i));
195
input = i_stream_create_from_data(in, strlen(in));
196
chunked = http_transfer_chunked_istream_create(input, 0);
198
buffer_set_used_size(payload_buffer, 0);
199
output = o_stream_create_buffer(payload_buffer);
200
(void)o_stream_send_istream(output, chunked);
201
test_out("payload read failure", chunked->stream_errno != 0);
202
o_stream_destroy(&output);
207
buffer_free(&payload_buffer);
210
/* Valid transfer_chunked output tests */
211
static const char *valid_transfer_chunked_output_tests[] = {
212
/* The maximum chunk size is set to 16. These tests are tuned to some border
215
"A small payload", // 15 bytes
216
"A longer payload", // 16 bytes
217
"A lengthy payload", // 17 bytes
219
"This is a test payload with lots of nonsense.",
220
"Yet another payload.",
221
"This a very long repetitive payload. This a very long repetitive payload. "
222
"This a very long repetitive payload. This a very long repetitive payload. "
223
"This a very long repetitive payload. This a very long repetitive payload. "
224
"This a very long repetitive payload. This a very long repetitive payload. "
225
"This a very long repetitive payload. This a very long repetitive payload. "
226
"This a very long repetitive payload. This a very long repetitive payload. "
227
"This a very long repetitive payload. This a very long repetitive payload. "
228
"This a very long repetitive payload. This a very long repetitive payload. "
229
"This a very long repetitive payload. This a very long repetitive payload. "
230
"This a very long repetitive payload. This a very long repetitive payload. "
231
"This a very long repetitive payload. This a very long repetitive payload. "
232
"This a very long repetitive payload. This a very long repetitive payload. "
233
"This a very long repetitive payload. This a very long repetitive payload. "
234
"This a very long repetitive payload. This a very long repetitive payload. "
235
"This a very long repetitive payload. This a very long repetitive payload. "
236
"This a very long repetitive payload. This a very long repetitive payload. "
237
"This a very long repetitive payload. This a very long repetitive payload. "
238
"This a very long repetitive payload. This a very long repetitive payload. "
239
"This a very long repetitive payload. This a very long repetitive payload. "
242
static unsigned int valid_transfer_chunked_output_test_count =
243
N_ELEMENTS(valid_transfer_chunked_output_tests);
245
static void test_http_transfer_chunked_output_valid(void)
247
struct istream *input, *ichunked;
248
struct ostream *output, *ochunked;
249
buffer_t *chunked_buffer, *plain_buffer;
252
chunked_buffer = buffer_create_dynamic(default_pool, 1024);
253
plain_buffer = buffer_create_dynamic(default_pool, 1024);
255
for (i = 0; i < valid_transfer_chunked_output_test_count; i++) T_BEGIN {
256
const char *data, *stream_out;
257
const unsigned char *rdata;
261
data = valid_transfer_chunked_output_tests[i];
263
test_begin(t_strdup_printf("http transfer_chunked output valid [%d]", i));
265
/* create input stream */
266
input = i_stream_create_from_data(data, strlen(data));
268
/* create buffer output stream */
269
buffer_set_used_size(chunked_buffer, 0);
270
output = o_stream_create_buffer(chunked_buffer);
272
/* create chunked output stream */
273
ochunked = http_transfer_chunked_ostream_create(output);
275
/* send input through chunked stream; chunk size is limited */
277
ret = i_stream_read_data(input, &rdata, &rsize, 0);
288
ret = o_stream_send(ochunked, rdata, rsize);
292
if ((size_t)ret != rsize) {
297
i_stream_skip(input, ret);
300
/* cleanup streams */
301
test_out("payload chunk", ret > 0);
302
o_stream_destroy(&ochunked);
303
o_stream_destroy(&output);
304
i_stream_destroy(&input);
306
/* create chunked input stream */
307
input = i_stream_create_from_data
308
(chunked_buffer->data, chunked_buffer->used);
309
ichunked = http_transfer_chunked_istream_create(input, 0);
311
/* read back chunk */
312
buffer_set_used_size(plain_buffer, 0);
313
output = o_stream_create_buffer(plain_buffer);
314
ret = o_stream_send_istream(output, ichunked);
315
test_out("payload unchunk", ret >= 0
316
&& ichunked->stream_errno == 0);
317
o_stream_destroy(&output);
318
i_stream_destroy(&ichunked);
319
i_stream_destroy(&input);
322
stream_out = str_c(plain_buffer);
323
test_out(t_strdup_printf("response->payload = %s",
324
str_sanitize(stream_out, 80)),
325
strcmp(stream_out, data) == 0);
329
buffer_free(&chunked_buffer);
330
buffer_free(&plain_buffer);
335
static void (*test_functions[])(void) = {
336
test_http_transfer_chunked_input_valid,
337
test_http_transfer_chunked_input_invalid,
338
test_http_transfer_chunked_output_valid,
341
return test_run(test_functions);