1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include "io.h"
30
31 #include "testutils.h"
32
33
34 UCX_TEST(test_io_http_stream_parse_chunk_header_hdronly_first) {
35 char *str = strdup(
"100\r\n");
36 size_t len = strlen(str);
37 char *str2 = strdup(
"12345\r\n");
38 size_t len2 = strlen(str2);
39 char *str3 = strdup(
"FF\r\n");
40 size_t len3 = strlen(str3);
41
42 UCX_TEST_BEGIN;
43
44 int64_t chunklen;
45 int ret = http_stream_parse_chunk_header(str, len,
TRUE, &chunklen);
46 UCX_TEST_ASSERT(ret ==
5,
"ret != 5");
47 UCX_TEST_ASSERT(chunklen == 0x100,
"wrong chunk length");
48
49
50 ret = http_stream_parse_chunk_header(str2, len2,
TRUE, &chunklen);
51 UCX_TEST_ASSERT(ret ==
7,
"ret != 7 (test 2)");
52 UCX_TEST_ASSERT(chunklen == 0x12345,
"wrong chunk length (test 2)");
53
54
55 ret = http_stream_parse_chunk_header(str3, len3,
TRUE, &chunklen);
56 UCX_TEST_ASSERT(ret ==
4,
"ret != 7 (test 3)");
57 UCX_TEST_ASSERT(chunklen == 0xFF,
"wrong chunk length (test 3)");
58
59 UCX_TEST_END;
60 free(str);
61 free(str2);
62 }
63
64 UCX_TEST(test_io_http_stream_parse_chunk_header_hdronly) {
65 char *str = strdup(
"\r\n100\r\n");
66 size_t len = strlen(str);
67 char *str2 = strdup(
"\nab\n");
68 size_t len2 = strlen(str2);
69
70 UCX_TEST_BEGIN;
71
72 int64_t chunklen;
73 int ret = http_stream_parse_chunk_header(str, len,
FALSE, &chunklen);
74 UCX_TEST_ASSERT(ret ==
7,
"ret != 7");
75 UCX_TEST_ASSERT(chunklen == 0x100,
"wrong chunk length");
76
77
78 ret = http_stream_parse_chunk_header(str2, len2,
FALSE, &chunklen);
79 UCX_TEST_ASSERT(ret ==
4,
"ret != 5 (test 2)");
80 UCX_TEST_ASSERT(chunklen == 0xab,
"wrong chunk length (test 2)");
81
82 UCX_TEST_END;
83 free(str);
84 free(str2);
85 }
86
87 UCX_TEST(test_io_http_stream_parse_chunk_header_hdronly_seq_fail) {
88
89 char *str = strdup(
"ff\r\n");
90 size_t len = strlen(str);
91
92 UCX_TEST_BEGIN;
93
94 int64_t chunklen;
95 int ret = http_stream_parse_chunk_header(str, len,
FALSE, &chunklen);
96 UCX_TEST_ASSERT(ret == -
1,
"ret != -1");
97
98 UCX_TEST_END;
99 free(str);
100 }
101
102 UCX_TEST(test_io_http_stream_parse_chunk_header_hdr_data) {
103 char *str = strdup(
"\r\nb\r\nhello world\r\n");
104 size_t len = strlen(str);
105
106 UCX_TEST_BEGIN;
107
108 int64_t chunklen;
109 int ret = http_stream_parse_chunk_header(str, len,
FALSE, &chunklen);
110 UCX_TEST_ASSERT(ret ==
5,
"ret != 5");
111
112 UCX_TEST_END;
113 free(str);
114 }
115
116 UCX_TEST(test_io_http_stream_parse_chunk_header_empty) {
117 char *str =
"";
118 size_t len = strlen(str);
119
120 UCX_TEST_BEGIN;
121
122 int64_t chunklen;
123 int ret = http_stream_parse_chunk_header(str, len,
FALSE, &chunklen);
124 UCX_TEST_ASSERT(ret ==
0,
"ret != 0");
125
126 ret = http_stream_parse_chunk_header(str, len,
TRUE, &chunklen);
127 UCX_TEST_ASSERT(ret ==
0,
"ret != 0 (test 2)");
128
129 UCX_TEST_END;
130 }
131
132 UCX_TEST(test_io_http_stream_parse_chunk_header_partial_first) {
133 char *str = strdup(
"123");
134 size_t len = strlen(str);
135
136 UCX_TEST_BEGIN;
137
138 int64_t chunklen;
139 int ret = http_stream_parse_chunk_header(str, len,
TRUE, &chunklen);
140 UCX_TEST_ASSERT(ret ==
0,
"ret != 0");
141
142 UCX_TEST_END;
143 free(str);
144 }
145
146 UCX_TEST(test_io_http_stream_parse_chunk_header_partial) {
147 char *str = strdup(
"123");
148 size_t len = strlen(str);
149 char *str2 = strdup(
"\r\n");
150 size_t len2 = strlen(str2);
151 char *str3 = strdup(
"\r");
152 size_t len3 = strlen(str3);
153 char *str4 = strdup(
"\r\n123");
154 size_t len4 = strlen(str4);
155
156 UCX_TEST_BEGIN;
157
158 int64_t chunklen;
159 int ret = http_stream_parse_chunk_header(str, len,
TRUE, &chunklen);
160 UCX_TEST_ASSERT(ret ==
0,
"ret != 0");
161 ret = http_stream_parse_chunk_header(str2, len2,
FALSE, &chunklen);
162 UCX_TEST_ASSERT(ret ==
0,
"ret != 0");
163 ret = http_stream_parse_chunk_header(str3, len3,
FALSE, &chunklen);
164 UCX_TEST_ASSERT(ret ==
0,
"ret != 0");
165 ret = http_stream_parse_chunk_header(str4, len4,
FALSE, &chunklen);
166 UCX_TEST_ASSERT(ret ==
0,
"ret != 0");
167
168 UCX_TEST_END;
169 free(str);
170 free(str2);
171 free(str3);
172 free(str4);
173 }
174
175 UCX_TEST(test_io_http_stream_parse_chunk_header_invalid) {
176 char *str = strdup(
"hello\r\n");
177 size_t len = strlen(str);
178 char *str2 = strdup(
"x4\r\n\r\n123\r\n");
179 size_t len2 = strlen(str2);
180 char *str3 = strdup(
"\r\n\r\n123\r\n");
181 size_t len3 = strlen(str3);
182 char *str4 = strdup(
"\r\n\r\nx123\r\n");
183 size_t len4 = strlen(str3);
184 char *str5 = strdup(
"\r\n\r\n1 2 3\r\n");
185 size_t len5 = strlen(str3);
186 char *str6 = strdup(
"\r\n\r\n1 23\r\n");
187 size_t len6 = strlen(str3);
188
189 UCX_TEST_BEGIN;
190
191 int64_t chunklen;
192 int ret;
193
194 ret = http_stream_parse_chunk_header(str, len,
TRUE, &chunklen);
195 UCX_TEST_ASSERT(ret == -
1,
"ret != -1 (test 1a)");
196 ret = http_stream_parse_chunk_header(str, len,
FALSE, &chunklen);
197 UCX_TEST_ASSERT(ret == -
1,
"ret != -1 (test 1b)");
198
199 ret = http_stream_parse_chunk_header(str2, len2,
TRUE, &chunklen);
200 UCX_TEST_ASSERT(ret == -
1,
"ret != -1 (test 2a)");
201 ret = http_stream_parse_chunk_header(str2, len2,
FALSE, &chunklen);
202 UCX_TEST_ASSERT(ret == -
1,
"ret != -1 (test 2b)");
203
204 ret = http_stream_parse_chunk_header(str3, len3,
TRUE, &chunklen);
205 UCX_TEST_ASSERT(ret == -
1,
"ret != -1 (test 3a)");
206 ret = http_stream_parse_chunk_header(str3, len3,
FALSE, &chunklen);
207 UCX_TEST_ASSERT(ret == -
1,
"ret != -1 (test 3b)");
208
209 ret = http_stream_parse_chunk_header(str4, len4,
TRUE, &chunklen);
210 UCX_TEST_ASSERT(ret == -
1,
"ret != -1 (test 4a)");
211 ret = http_stream_parse_chunk_header(str4, len4,
FALSE, &chunklen);
212 UCX_TEST_ASSERT(ret == -
1,
"ret != -1 (test 4b)");
213
214 ret = http_stream_parse_chunk_header(str5, len5,
TRUE, &chunklen);
215 UCX_TEST_ASSERT(ret == -
1,
"ret != -1 (test 5a)");
216 ret = http_stream_parse_chunk_header(str5, len5,
FALSE, &chunklen);
217 UCX_TEST_ASSERT(ret == -
1,
"ret != -1 (test 5b)");
218
219 ret = http_stream_parse_chunk_header(str6, len6,
TRUE, &chunklen);
220 UCX_TEST_ASSERT(ret == -
1,
"ret != -1 (test 6a)");
221 ret = http_stream_parse_chunk_header(str6, len6,
FALSE, &chunklen);
222 UCX_TEST_ASSERT(ret == -
1,
"ret != -1 (test 6b)");
223
224 UCX_TEST_END;
225 free(str);
226 free(str2);
227 free(str3);
228 free(str4);
229 free(str5);
230 free(str6);
231 }
232
233 UCX_TEST(test_io_http_stream_parse_chunk_header_zero) {
234 char *str = strdup(
"\r\n0\r\n\r\n");
235 size_t len = strlen(str);
236 char *str2 = strdup(
"0\r\n\r\n");
237 size_t len2 = strlen(str2);
238
239
240 char *str3 = strdup(
"\r\n0\r\n");
241 size_t len3 = strlen(str3);
242 char *str4 = strdup(
"\r\n0");
243 size_t len4 = strlen(str4);
244
245
246 UCX_TEST_BEGIN;
247
248 int64_t chunklen = -
1;
249 int ret = http_stream_parse_chunk_header(str, len,
FALSE, &chunklen);
250 UCX_TEST_ASSERT(ret ==
7,
"ret != 7");
251 UCX_TEST_ASSERT(chunklen ==
0,
"chunklen != 0");
252
253 chunklen = -
1;
254 ret = http_stream_parse_chunk_header(str2, len2,
TRUE, &chunklen);
255 UCX_TEST_ASSERT(ret ==
5,
"ret != 5 (test 2)");
256 UCX_TEST_ASSERT(chunklen ==
0,
"chunklen != 0 (test 2)");
257
258
259 ret = http_stream_parse_chunk_header(str3, len3,
FALSE, &chunklen);
260 UCX_TEST_ASSERT(ret ==
0,
"ret != 3 (test 3)");
261
262 ret = http_stream_parse_chunk_header(str4, len4,
FALSE, &chunklen);
263 UCX_TEST_ASSERT(ret ==
0,
"ret != 3 (test 4)");
264
265 UCX_TEST_END;
266 free(str);
267 free(str2);
268 free(str3);
269 free(str4);
270 }
271
272
273 UCX_TEST(test_io_httpstream_write) {
274 Session *sn = testutil_session();
275
276 TestIOStream *st = testutil_iostream(
2048,
TRUE);
277 IOStream *http = httpstream_new(sn->pool, (IOStream*)st);
278
279 UCX_TEST_BEGIN;
280
281 char *msg =
"hello world!";
282 size_t msglen = strlen(msg);
283
284 ssize_t w = net_write(http, msg, msglen);
285
286 UCX_TEST_ASSERT(w == msglen,
"wrong size returned by net_write");
287 UCX_TEST_ASSERT(st->buf->size == msglen,
"wrong buffer size");
288 UCX_TEST_ASSERT(!memcmp(st->buf->space, msg, msglen),
"wrong buffer content");
289
290
291 char *msg2 =
"test";
292 size_t msglen2 = strlen(msg2);
293
294 w = net_write(http, msg2, msglen2);
295
296 UCX_TEST_ASSERT(w == msglen2,
"wrong size returned by net_write (2)");
297 UCX_TEST_ASSERT(st->buf->size == msglen+msglen2,
"wrong buffer size (2)");
298 UCX_TEST_ASSERT(!memcmp(st->buf->space + msglen, msg2, msglen2),
"wrong buffer content (2)");
299
300 UCX_TEST_END;
301
302 testutil_destroy_session(sn);
303 }
304
305 UCX_TEST(test_io_httpstream_chunked_write) {
306 Session *sn = testutil_session();
307
308 TestIOStream *st = testutil_iostream(
2048,
TRUE);
309 IOStream *http = httpstream_new(sn->pool, (IOStream*)st);
310 httpstream_enable_chunked_write(http);
311
312 UCX_TEST_BEGIN;
313
314 char *msg =
"hello world!";
315 size_t msglen = strlen(msg);
316
317 char *bufmsg =
"c\r\nhello world!\r\n";
318 size_t bufmsglen = strlen(bufmsg);
319
320 ssize_t w = net_write(http, msg, msglen);
321
322 cxstring s1 = cx_strn(st->buf->space, st->buf->size);
323 cxstring s2 = cx_strn(bufmsg, bufmsglen);
324
325 UCX_TEST_ASSERT(w == msglen,
"wrong size returned by net_write");
326 UCX_TEST_ASSERT(st->buf->size == bufmsglen,
"wrong buffer size");
327 UCX_TEST_ASSERT(!cx_strcasecmp(s1, s2),
"wrong buffer content");
328
329
330 w = net_write(http, msg, msglen);
331 UCX_TEST_ASSERT(w == msglen,
"write 2: wrong return value");
332 UCX_TEST_ASSERT(st->buf->size ==
2*bufmsglen,
"write 2: wrong buf size");
333
334 cxstring s3 = cx_strn(st->buf->space+bufmsglen, bufmsglen);
335 UCX_TEST_ASSERT(!cx_strcasecmp(s2, s3),
"write 2: wrong buf content");
336
337
338 UCX_TEST_END;
339 }
340
341 UCX_TEST(test_io_httpstream_chunked_write_end) {
342 Session *sn = testutil_session();
343
344 TestIOStream *st = testutil_iostream(
2048,
TRUE);
345 IOStream *http = httpstream_new(sn->pool, (IOStream*)st);
346 httpstream_enable_chunked_write(http);
347
348 UCX_TEST_BEGIN;
349
350 char *msg =
"hello world!";
351 size_t msglen = strlen(msg);
352
353 char *bufmsg =
"c\r\nhello world!\r\n0\r\n\r\n";
354 size_t bufmsglen = strlen(bufmsg);
355
356 ssize_t w = net_write(http, msg, msglen);
357 net_finish(http);
358
359 cxstring s1 = cx_strn(st->buf->space, st->buf->size);
360 cxstring s2 = cx_strn(bufmsg, bufmsglen);
361
362 UCX_TEST_ASSERT(w == msglen,
"wrong size returned by net_write");
363 UCX_TEST_ASSERT(st->buf->size == bufmsglen,
"wrong buffer size");
364 UCX_TEST_ASSERT(!cx_strcasecmp(s1, s2),
"wrong buffer content");
365
366
367 UCX_TEST_END;
368 }
369
370 UCX_TEST(test_io_httpstream_chunked_write_xx) {
371
372
373
374 Session *sn = testutil_session();
375
376 TestIOStream *st = testutil_iostream(
2048,
TRUE);
377 IOStream *http = httpstream_new(sn->pool, (IOStream*)st);
378 httpstream_enable_chunked_write(http);
379
380 UCX_TEST_BEGIN;
381
382
383 CxBuffer *testdata = cxBufferCreate(
NULL,
1024*
1024*
4, cxDefaultAllocator,
0);
384 for(
size_t i=
0;i<testdata->capacity;i++) {
385 cxBufferPut(testdata,
35+(i%
91));
386 }
387
388
389
390 size_t pos =
0;
391 int j =
0;
392 ssize_t i=
15;
393 while(pos<testdata->size) {
394 char *buf = testdata->space + pos;
395 size_t remaining = testdata->size - pos;
396 ssize_t len = pos + i < remaining ? i : remaining;
397 pos += len;
398
399 ssize_t w = net_write(http, buf, len);
400
401 UCX_TEST_ASSERT(w == len,
"wrong size returned by net_write");
402 i+=
100;
403 j++;
404 }
405
406
407 net_finish(http);
408
409
410
411
412
413
414 WSBool first_chunk =
TRUE;
415 int64_t chunklen =
0;
416
417 char *buf = st->buf->space;
418 size_t bufsize = st->buf->size;
419
420 pos =
0;
421 size_t srcpos =
0;
422 int debug_counter =
0;
423 while(pos < bufsize) {
424 ssize_t remaining = bufsize - pos;
425 ssize_t src_remaining = testdata->size - srcpos;
426
427 int ret = http_stream_parse_chunk_header(buf+pos, remaining, first_chunk, &chunklen);
428 first_chunk =
FALSE;
429
430
431 UCX_TEST_ASSERT(ret >
0,
"http_stream_parse_chunk_header ret <= 0");
432 if(chunklen ==
0) {
433 UCX_TEST_ASSERT(src_remaining ==
0,
"stream end reached but src_remaining > 0");
434 break;
435 }
436
437 UCX_TEST_ASSERT(chunklen <= src_remaining,
"chunklen > src_remaining");
438
439 char *src_chunk = testdata->space+srcpos;
440 char *buf_chunk = buf+pos+ret;
441
442 UCX_TEST_ASSERT(!memcmp(buf_chunk, src_chunk, chunklen),
"memcmp failed");
443
444 pos += ret + chunklen;
445 srcpos += chunklen;
446
447 debug_counter++;
448 }
449
450 cxBufferFree(testdata);
451 testutil_destroy_session(sn);
452 testutil_iostream_destroy(st);
453
454 UCX_TEST_END;
455 }
456
457 UCX_TEST(test_io_httpstream_chunked_write_partial_header) {
458 Session *sn = testutil_session();
459
460 TestIOStream *st = testutil_iostream(
2048,
TRUE);
461 IOStream *http = httpstream_new(sn->pool, (IOStream*)st);
462 httpstream_enable_chunked_write(http);
463
464 UCX_TEST_BEGIN;
465
466 memset(st->buf->space,
0, st->buf->capacity);
467
468 char *msg =
"hello world!";
469 size_t msglen = strlen(msg);
470
471 st->max_write =
1;
472 io_set_max_writes(
1);
473
474
475 ssize_t w = net_write(http, msg, msglen);
476 UCX_TEST_ASSERT(w ==
0,
"write 1: wrong return value");
477 UCX_TEST_ASSERT(st->buf->size ==
1,
"write 1: wrong buf size");
478 UCX_TEST_ASSERT(tolower(st->buf->space[
0]) ==
'c',
"write 1: wrong buf content");
479
480
481 w = net_write(http, msg, msglen);
482 UCX_TEST_ASSERT(w ==
0,
"write 2: wrong return value");
483 UCX_TEST_ASSERT(st->buf->size ==
2,
"write 2: wrong buf size");
484 UCX_TEST_ASSERT(st->buf->space[
1] ==
'\r',
"write 2: wrong content");
485
486
487 w = net_write(http, msg, msglen);
488 UCX_TEST_ASSERT(w ==
0,
"write 3: wrong return value");
489 UCX_TEST_ASSERT(st->buf->size ==
3,
"write 3: wrong buf size");
490 UCX_TEST_ASSERT(st->buf->space[
2] ==
'\n',
"write 3: wrong content");
491
492
493 w = net_write(http, msg, msglen);
494 UCX_TEST_ASSERT(w ==
1,
"write 4: wrong return value");
495 UCX_TEST_ASSERT(st->buf->size ==
4,
"write 3: wrong buf size");
496 UCX_TEST_ASSERT(st->buf->space[
3] == msg[
0],
"write 3: wrong content");
497
498 testutil_destroy_session(sn);
499 testutil_iostream_destroy(st);
500
501 UCX_TEST_END;
502 }
503
504 UCX_TEST(test_io_httpstream_chunked_write_partial_data) {
505 Session *sn = testutil_session();
506
507 TestIOStream *st = testutil_iostream(
2048,
TRUE);
508 IOStream *http = httpstream_new(sn->pool, (IOStream*)st);
509 httpstream_enable_chunked_write(http);
510
511 UCX_TEST_BEGIN;
512
513 memset(st->buf->space,
0, st->buf->capacity);
514
515 char *msg =
"hello world!";
516 size_t msglen = strlen(msg);
517 size_t msglen_orig = msglen;
518
519
520 st->max_write =
3;
521 io_set_max_writes(
1);
522
523 ssize_t w = net_write(http, msg, msglen);
524
525 UCX_TEST_ASSERT(w ==
0,
"write 1: wrong return value");
526 UCX_TEST_ASSERT(st->buf->size ==
3,
"write 1: wrong buf size");
527 UCX_TEST_ASSERT(st->buf->space[
0] ==
'c',
"write 1: wrong buf content");
528 UCX_TEST_ASSERT(st->buf->space[
2] ==
'\n',
"write 1: wrong buf content");
529
530 w = net_write(http, msg, msglen);
531 UCX_TEST_ASSERT(w ==
3,
"write 2: wrong return value");
532 UCX_TEST_ASSERT(st->buf->size ==
6,
"write 2: wrong buf size");
533 UCX_TEST_ASSERT(!memcmp(st->buf->space,
"c\r\nhel\0",
7),
"write 2: wrong buf content");
534
535 msg += w;
536 msglen -= w;
537
538 w = net_write(http, msg, msglen);
539 UCX_TEST_ASSERT(w ==
3,
"write 3: wrong return value");
540 UCX_TEST_ASSERT(st->buf->size ==
9,
"write 3: wrong buf size");
541 UCX_TEST_ASSERT(!memcmp(st->buf->space,
"c\r\nhello \0",
10),
"write 3: wrong buf content");
542
543 st->max_write =
1024;
544 msg += w;
545 msglen -= w;
546
547 w = net_write(http, msg, msglen);
548 UCX_TEST_ASSERT(w == msglen,
"write 4: wrong return value");
549 UCX_TEST_ASSERT(st->buf->size ==
3 + msglen_orig +
2,
"write 4: wrong buf size");
550 UCX_TEST_ASSERT(!memcmp(st->buf->space,
"c\r\nhello world!\r\n", st->buf->size),
"write 4: wrong buf content");
551
552 testutil_destroy_session(sn);
553 testutil_iostream_destroy(st);
554
555 UCX_TEST_END;
556 }
557
558 UCX_TEST(test_io_httpstream_chunked_write_partial_trailer) {
559 Session *sn = testutil_session();
560
561 TestIOStream *st = testutil_iostream(
2048,
TRUE);
562 IOStream *http = httpstream_new(sn->pool, (IOStream*)st);
563 httpstream_enable_chunked_write(http);
564 io_set_max_writes(
1);
565
566 UCX_TEST_BEGIN;
567
568 memset(st->buf->space,
0, st->buf->capacity);
569
570 char *msg =
"hello world!";
571 size_t msglen = strlen(msg);
572
573 char *msg2 =
"newmsg";
574 size_t msglen2 = strlen(msg2);
575
576 char *msg3 =
"msg3";
577 size_t msglen3 = strlen(msg3);
578
579 st->max_write =
3 + msglen;
580
581 ssize_t w = net_write(http, msg, msglen);
582
583 UCX_TEST_ASSERT(w == msglen,
"write 1: wrong return value");
584 UCX_TEST_ASSERT(st->buf->size ==
3 + msglen,
"write 1: wrong buf size");
585 UCX_TEST_ASSERT(!memcmp(st->buf->space,
"c\r\nhello world!\0", st->buf->size +
1),
"write 1: wrong buf content");
586
587 st->max_write =
2 +
3 + msglen2;
588
589 w = net_write(http, msg2, msglen2);
590 UCX_TEST_ASSERT(w == msglen2,
"write 2: wrong return value");
591 UCX_TEST_ASSERT(st->buf->size ==
3 + msglen +
2 +
3 + msglen2,
"write 2: wrong buf size");
592 UCX_TEST_ASSERT(!memcmp(st->buf->space,
"c\r\nhello world!\r\n6\r\nnewmsg\0", st->buf->size +
1),
"write 2: wrong buf content");
593
594
595 st->max_write =
1;
596
597 w = net_write(http,
"dummymsg",
8);
598 UCX_TEST_ASSERT(w ==
0,
"write 3: wrong return value");
599
600 w = net_write(http,
"dummymsg",
8);
601 UCX_TEST_ASSERT(w ==
0,
"write 4: wrong return value");
602 UCX_TEST_ASSERT(st->buf->size ==
3 + msglen +
2 +
3 + msglen2 +
2,
"write 4: wrong buf size");
603 UCX_TEST_ASSERT(!memcmp(st->buf->space,
"c\r\nhello world!\r\n6\r\nnewmsg\r\n\0", st->buf->size +
1),
"write 4: wrong buf content");
604
605 st->max_write =
1024;
606 w = net_write(http, msg3, msglen3);
607
608 UCX_TEST_ASSERT(w == msglen3,
"write 5: wrong return value");
609 UCX_TEST_ASSERT(st->buf->size ==
3 + msglen +
2 +
3 + msglen2 +
2 +
3 + msglen3 +
2,
"write 5: wrong buf size");
610 UCX_TEST_ASSERT(!memcmp(st->buf->space,
"c\r\nhello world!\r\n6\r\nnewmsg\r\n4\r\nmsg3\r\n", st->buf->size +
1),
"write 5: wrong buf content");
611
612
613 testutil_destroy_session(sn);
614 testutil_iostream_destroy(st);
615
616 UCX_TEST_END;
617 }
618
619 UCX_TEST(test_io_httpstream_chunked_write_partial_trailer_partial_header) {
620 Session *sn = testutil_session();
621
622 TestIOStream *st = testutil_iostream(
2048,
TRUE);
623 IOStream *http = httpstream_new(sn->pool, (IOStream*)st);
624 httpstream_enable_chunked_write(http);
625 io_set_max_writes(
1);
626
627 UCX_TEST_BEGIN;
628
629 memset(st->buf->space,
0, st->buf->capacity);
630
631 char *msg =
"hello world!";
632 size_t msglen = strlen(msg);
633
634 char *msg2 =
"newmsg";
635 size_t msglen2 = strlen(msg2);
636
637
638
639 st->max_write =
3 + msglen +
1;
640
641 ssize_t w = net_write(http, msg, msglen);
642
643 UCX_TEST_ASSERT(w == msglen,
"write 1: wrong return value");
644 UCX_TEST_ASSERT(st->buf->size ==
3 + msglen +
1,
"write 1: wrong buf size");
645 UCX_TEST_ASSERT(!memcmp(st->buf->space,
"c\r\nhello world!\r\0", st->buf->size +
1),
"write 1: wrong buf content");
646
647 st->max_write =
2;
648
649 w = net_write(http, msg2, msglen2);
650
651 UCX_TEST_ASSERT(w ==
0,
"write 2: wrong return value");
652 UCX_TEST_ASSERT(st->buf->size ==
3 + msglen +
2 +
1,
"write 2: wrong buf size");
653 UCX_TEST_ASSERT(!memcmp(st->buf->space,
"c\r\nhello world!\r\n6\0", st->buf->size +
1),
"write 2: wrong buf content");
654
655
656 st->max_write =
1;
657
658 w = net_write(http, msg2, msglen2);
659
660 UCX_TEST_ASSERT(w ==
0,
"write 3: wrong return value");
661 UCX_TEST_ASSERT(st->buf->size ==
3 + msglen +
2 +
2,
"write 3: wrong buf size");
662 UCX_TEST_ASSERT(!memcmp(st->buf->space,
"c\r\nhello world!\r\n6\r\0", st->buf->size +
1),
"write 3: wrong buf content");
663
664 st->max_write =
1024;
665
666 w = net_write(http, msg2, msglen2);
667
668 UCX_TEST_ASSERT(w ==msglen2,
"write 4: wrong return value");
669 UCX_TEST_ASSERT(st->buf->size ==
3 + msglen +
2 +
3 + msglen2 +
2,
"write 4: wrong buf size");
670 UCX_TEST_ASSERT(!memcmp(st->buf->space,
"c\r\nhello world!\r\n6\r\nnewmsg\r\n", st->buf->size +
1),
"write 4: wrong buf content");
671
672
673 testutil_destroy_session(sn);
674 testutil_iostream_destroy(st);
675
676 UCX_TEST_END;
677 }
678
679 UCX_TEST(test_io_httpstream_chunked_write_data_2x) {
680 Session *sn = testutil_session();
681
682 TestIOStream *st = testutil_iostream(
2048,
TRUE);
683 IOStream *http = httpstream_new(sn->pool, (IOStream*)st);
684 httpstream_enable_chunked_write(http);
685 io_set_max_writes(
1);
686
687 UCX_TEST_BEGIN;
688
689 memset(st->buf->space,
0, st->buf->capacity);
690
691
692
693
694
695 char *msg =
"hello world!";
696 size_t msglen = strlen(msg);
697
698 char *msg2 =
"newmsg";
699 size_t msglen2 = strlen(msg2);
700
701 char *msg_big =
"hello world!newmsg";
702 size_t msglen_big = strlen(msg_big);
703
704 st->max_write =
1;
705
706 ssize_t w = net_write(http, msg, msglen);
707
708 UCX_TEST_ASSERT(w ==
0,
"write 1: wrong return value");
709 UCX_TEST_ASSERT(st->buf->size ==
1,
"write 1: wrong buf size");
710
711 st->max_write =
1024;
712
713 w = net_write(http, msg_big, msglen_big);
714
715 UCX_TEST_ASSERT(w == msglen_big,
"write 2: wrong return value");
716 UCX_TEST_ASSERT(st->buf->size ==
3 + msglen +
2 +
3 + msglen2 +
2,
"write 2: wrong buf size");
717 UCX_TEST_ASSERT(!memcmp(st->buf->space,
"c\r\nhello world!\r\n6\r\nnewmsg\r\n", st->buf->size +
1),
"write 2: wrong buf content");
718
719
720 testutil_destroy_session(sn);
721 testutil_iostream_destroy(st);
722
723 UCX_TEST_END;
724 }
725
726 UCX_TEST(test_io_httpstream_chunked_write_xx_limit) {
727 Session *sn = testutil_session();
728
729 TestIOStream *st = testutil_iostream(
2048,
TRUE);
730 IOStream *http = httpstream_new(sn->pool, (IOStream*)st);
731 httpstream_enable_chunked_write(http);
732 io_set_max_writes(
1);
733
734 UCX_TEST_BEGIN;
735
736
737
738
739
740 CxBuffer *testdata = cxBufferCreate(
NULL,
1024*
16, cxDefaultAllocator,
0);
741 for(
size_t i=
0;i<testdata->capacity;i++) {
742 cxBufferPut(testdata,
35+(i%
91));
743 }
744
745 st->max_write =
1;
746
747 size_t pos =
0;
748 int chunksize =
1;
749 while(pos < testdata->size) {
750 size_t available = testdata->size - pos;
751
752 char *chunk = testdata->space + pos;
753 size_t chunklen = chunksize > available ? available : chunksize;
754
755
756 size_t chunkpos =
0;
757 int max_writes = chunklen +
24;
758 int writes =
0;
759 while(chunkpos < chunklen) {
760 ssize_t w = net_write(http, chunk+chunkpos, chunklen-chunkpos);
761 UCX_TEST_ASSERT(w >=
0,
"net_write failed");
762 chunkpos += w;
763
764 writes++;
765 UCX_TEST_ASSERT(writes < max_writes,
"max writes attempts reached");
766 }
767
768 pos += chunklen;
769 chunksize +=
5;
770
771
772 if(pos + chunksize >= testdata->size) {
773 st->max_write =
INT_MAX;
774 }
else if(pos >
1024*
2) {
775 if(pos <
1024*
8) {
776 st->max_write =
2;
777 }
else {
778 st->max_write =
3;
779 }
780 }
781 }
782
783
784 net_finish(http);
785
786
787
788
789
790
791
792
793 WSBool first_chunk =
TRUE;
794 int64_t chunklen =
0;
795
796 char *buf = st->buf->space;
797 size_t bufsize = st->buf->size;
798
799 pos =
0;
800 size_t srcpos =
0;
801 int debug_counter =
0;
802 while(pos < bufsize) {
803 ssize_t remaining = bufsize - pos;
804 ssize_t src_remaining = testdata->size - srcpos;
805
806 int ret = http_stream_parse_chunk_header(buf+pos, remaining, first_chunk, &chunklen);
807 first_chunk =
FALSE;
808
809
810 UCX_TEST_ASSERT(ret >
0,
"http_stream_parse_chunk_header ret <= 0");
811 if(chunklen ==
0) {
812 UCX_TEST_ASSERT(src_remaining ==
0,
"stream end reached but src_remaining > 0");
813 break;
814 }
815
816 UCX_TEST_ASSERT(chunklen <= src_remaining,
"chunklen > src_remaining");
817
818 char *src_chunk = testdata->space+srcpos;
819 char *buf_chunk = buf+pos+ret;
820
821 UCX_TEST_ASSERT(!memcmp(buf_chunk, src_chunk, chunklen),
"memcmp failed");
822
823 pos += ret + chunklen;
824 srcpos += chunklen;
825
826 debug_counter++;
827 }
828
829
830 testutil_destroy_session(sn);
831 testutil_iostream_destroy(st);
832 cxBufferFree(testdata);
833
834 UCX_TEST_END;
835 }
836