--- a/src/server/test/io.c Sat Nov 22 12:49:20 2025 +0100 +++ b/src/server/test/io.c Sat Nov 22 14:27:01 2025 +0100 @@ -31,7 +31,7 @@ #include "testutils.h" -UCX_TEST(test_io_http_stream_parse_chunk_header_hdronly_first) { +CX_TEST(test_io_http_stream_parse_chunk_header_hdronly_first) { char *str = strdup("100\r\n"); size_t len = strlen(str); char *str2 = strdup("12345\r\n"); @@ -39,111 +39,111 @@ char *str3 = strdup("FF\r\n"); size_t len3 = strlen(str3); - UCX_TEST_BEGIN; - - int64_t chunklen; - int ret = http_stream_parse_chunk_header(str, len, TRUE, &chunklen); - UCX_TEST_ASSERT(ret == 5, "ret != 5"); - UCX_TEST_ASSERT(chunklen == 0x100, "wrong chunk length"); + CX_TEST_DO { - // test 2 - ret = http_stream_parse_chunk_header(str2, len2, TRUE, &chunklen); - UCX_TEST_ASSERT(ret == 7, "ret != 7 (test 2)"); - UCX_TEST_ASSERT(chunklen == 0x12345, "wrong chunk length (test 2)"); - - // test 3: hex test - ret = http_stream_parse_chunk_header(str3, len3, TRUE, &chunklen); - UCX_TEST_ASSERT(ret == 4, "ret != 7 (test 3)"); - UCX_TEST_ASSERT(chunklen == 0xFF, "wrong chunk length (test 3)"); + int64_t chunklen; + int ret = http_stream_parse_chunk_header(str, len, TRUE, &chunklen); + CX_TEST_ASSERT(ret == 5); + CX_TEST_ASSERT(chunklen == 0x100); + + // test 2 + ret = http_stream_parse_chunk_header(str2, len2, TRUE, &chunklen); + CX_TEST_ASSERT(ret == 7); + CX_TEST_ASSERT(chunklen == 0x12345); + + // test 3: hex test + ret = http_stream_parse_chunk_header(str3, len3, TRUE, &chunklen); + CX_TEST_ASSERT(ret == 4); + CX_TEST_ASSERT(chunklen == 0xFF); - UCX_TEST_END; + } free(str); free(str2); } -UCX_TEST(test_io_http_stream_parse_chunk_header_hdronly) { +CX_TEST(test_io_http_stream_parse_chunk_header_hdronly) { char *str = strdup("\r\n100\r\n"); size_t len = strlen(str); char *str2 = strdup("\nab\n"); size_t len2 = strlen(str2); - UCX_TEST_BEGIN; - - int64_t chunklen; - int ret = http_stream_parse_chunk_header(str, len, FALSE, &chunklen); - UCX_TEST_ASSERT(ret == 7, "ret != 7"); - UCX_TEST_ASSERT(chunklen == 0x100, "wrong chunk length"); + CX_TEST_DO { - // test 2 with just \n as line break - ret = http_stream_parse_chunk_header(str2, len2, FALSE, &chunklen); - UCX_TEST_ASSERT(ret == 4, "ret != 5 (test 2)"); - UCX_TEST_ASSERT(chunklen == 0xab, "wrong chunk length (test 2)"); + int64_t chunklen; + int ret = http_stream_parse_chunk_header(str, len, FALSE, &chunklen); + CX_TEST_ASSERT(ret == 7); + CX_TEST_ASSERT(chunklen == 0x100); + + // test 2 with just \n as line break + ret = http_stream_parse_chunk_header(str2, len2, FALSE, &chunklen); + CX_TEST_ASSERT(ret == 4); + CX_TEST_ASSERT(chunklen == 0xab); - UCX_TEST_END; + } free(str); free(str2); } -UCX_TEST(test_io_http_stream_parse_chunk_header_hdronly_seq_fail) { +CX_TEST(test_io_http_stream_parse_chunk_header_hdronly_seq_fail) { // test: after the first chunk header, \r\n is required before any new header char *str = strdup("ff\r\n"); size_t len = strlen(str); - UCX_TEST_BEGIN; + CX_TEST_DO { - int64_t chunklen; - int ret = http_stream_parse_chunk_header(str, len, FALSE, &chunklen); - UCX_TEST_ASSERT(ret == -1, "ret != -1"); + int64_t chunklen; + int ret = http_stream_parse_chunk_header(str, len, FALSE, &chunklen); + CX_TEST_ASSERT(ret == -1); - UCX_TEST_END; + } free(str); } -UCX_TEST(test_io_http_stream_parse_chunk_header_hdr_data) { +CX_TEST(test_io_http_stream_parse_chunk_header_hdr_data) { char *str = strdup("\r\nb\r\nhello world\r\n"); size_t len = strlen(str); - UCX_TEST_BEGIN; + CX_TEST_DO { - int64_t chunklen; - int ret = http_stream_parse_chunk_header(str, len, FALSE, &chunklen); - UCX_TEST_ASSERT(ret == 5, "ret != 5"); + int64_t chunklen; + int ret = http_stream_parse_chunk_header(str, len, FALSE, &chunklen); + CX_TEST_ASSERT(ret == 5); - UCX_TEST_END; + } free(str); } -UCX_TEST(test_io_http_stream_parse_chunk_header_empty) { +CX_TEST(test_io_http_stream_parse_chunk_header_empty) { char *str = ""; size_t len = strlen(str); - UCX_TEST_BEGIN; + CX_TEST_DO { - int64_t chunklen; - int ret = http_stream_parse_chunk_header(str, len, FALSE, &chunklen); - UCX_TEST_ASSERT(ret == 0, "ret != 0"); - - ret = http_stream_parse_chunk_header(str, len, TRUE, &chunklen); - UCX_TEST_ASSERT(ret == 0, "ret != 0 (test 2)"); + int64_t chunklen; + int ret = http_stream_parse_chunk_header(str, len, FALSE, &chunklen); + CX_TEST_ASSERT(ret == 0); + + ret = http_stream_parse_chunk_header(str, len, TRUE, &chunklen); + CX_TEST_ASSERT(ret == 0); - UCX_TEST_END; + } } -UCX_TEST(test_io_http_stream_parse_chunk_header_partial_first) { +CX_TEST(test_io_http_stream_parse_chunk_header_partial_first) { char *str = strdup("123"); size_t len = strlen(str); - UCX_TEST_BEGIN; + CX_TEST_DO { - int64_t chunklen; - int ret = http_stream_parse_chunk_header(str, len, TRUE, &chunklen); - UCX_TEST_ASSERT(ret == 0, "ret != 0"); + int64_t chunklen; + int ret = http_stream_parse_chunk_header(str, len, TRUE, &chunklen); + CX_TEST_ASSERT(ret == 0); - UCX_TEST_END; + } free(str); } -UCX_TEST(test_io_http_stream_parse_chunk_header_partial) { +CX_TEST(test_io_http_stream_parse_chunk_header_partial) { char *str = strdup("123"); size_t len = strlen(str); char *str2 = strdup("\r\n"); @@ -153,26 +153,26 @@ char *str4 = strdup("\r\n123"); size_t len4 = strlen(str4); - UCX_TEST_BEGIN; + CX_TEST_DO { - int64_t chunklen; - int ret = http_stream_parse_chunk_header(str, len, TRUE, &chunklen); - UCX_TEST_ASSERT(ret == 0, "ret != 0"); - ret = http_stream_parse_chunk_header(str2, len2, FALSE, &chunklen); - UCX_TEST_ASSERT(ret == 0, "ret != 0"); - ret = http_stream_parse_chunk_header(str3, len3, FALSE, &chunklen); - UCX_TEST_ASSERT(ret == 0, "ret != 0"); - ret = http_stream_parse_chunk_header(str4, len4, FALSE, &chunklen); - UCX_TEST_ASSERT(ret == 0, "ret != 0"); + int64_t chunklen; + int ret = http_stream_parse_chunk_header(str, len, TRUE, &chunklen); + CX_TEST_ASSERT(ret == 0); + ret = http_stream_parse_chunk_header(str2, len2, FALSE, &chunklen); + CX_TEST_ASSERT(ret == 0); + ret = http_stream_parse_chunk_header(str3, len3, FALSE, &chunklen); + CX_TEST_ASSERT(ret == 0); + ret = http_stream_parse_chunk_header(str4, len4, FALSE, &chunklen); + CX_TEST_ASSERT(ret == 0); - UCX_TEST_END; + } free(str); free(str2); free(str3); free(str4); } -UCX_TEST(test_io_http_stream_parse_chunk_header_invalid) { +CX_TEST(test_io_http_stream_parse_chunk_header_invalid) { char *str = strdup("hello\r\n"); size_t len = strlen(str); char *str2 = strdup("x4\r\n\r\n123\r\n"); @@ -186,42 +186,41 @@ char *str6 = strdup("\r\n\r\n1 23\r\n"); size_t len6 = strlen(str3); - UCX_TEST_BEGIN; - - int64_t chunklen; - int ret; - - ret = http_stream_parse_chunk_header(str, len, TRUE, &chunklen); - UCX_TEST_ASSERT(ret == -1, "ret != -1 (test 1a)"); - ret = http_stream_parse_chunk_header(str, len, FALSE, &chunklen); - UCX_TEST_ASSERT(ret == -1, "ret != -1 (test 1b)"); - - ret = http_stream_parse_chunk_header(str2, len2, TRUE, &chunklen); - UCX_TEST_ASSERT(ret == -1, "ret != -1 (test 2a)"); - ret = http_stream_parse_chunk_header(str2, len2, FALSE, &chunklen); - UCX_TEST_ASSERT(ret == -1, "ret != -1 (test 2b)"); + CX_TEST_DO { + int64_t chunklen; + int ret; + + ret = http_stream_parse_chunk_header(str, len, TRUE, &chunklen); + CX_TEST_ASSERT(ret == -1); + ret = http_stream_parse_chunk_header(str, len, FALSE, &chunklen); + CX_TEST_ASSERT(ret == -1); + + ret = http_stream_parse_chunk_header(str2, len2, TRUE, &chunklen); + CX_TEST_ASSERT(ret == -1); + ret = http_stream_parse_chunk_header(str2, len2, FALSE, &chunklen); + CX_TEST_ASSERT(ret == -1); + + ret = http_stream_parse_chunk_header(str3, len3, TRUE, &chunklen); + CX_TEST_ASSERT(ret == -1); + ret = http_stream_parse_chunk_header(str3, len3, FALSE, &chunklen); + CX_TEST_ASSERT(ret == -1); + + ret = http_stream_parse_chunk_header(str4, len4, TRUE, &chunklen); + CX_TEST_ASSERT(ret == -1); + ret = http_stream_parse_chunk_header(str4, len4, FALSE, &chunklen); + CX_TEST_ASSERT(ret == -1); + + ret = http_stream_parse_chunk_header(str5, len5, TRUE, &chunklen); + CX_TEST_ASSERT(ret == -1); + ret = http_stream_parse_chunk_header(str5, len5, FALSE, &chunklen); + CX_TEST_ASSERT(ret == -1); + + ret = http_stream_parse_chunk_header(str6, len6, TRUE, &chunklen); + CX_TEST_ASSERT(ret == -1); + ret = http_stream_parse_chunk_header(str6, len6, FALSE, &chunklen); + CX_TEST_ASSERT(ret == -1); + } - ret = http_stream_parse_chunk_header(str3, len3, TRUE, &chunklen); - UCX_TEST_ASSERT(ret == -1, "ret != -1 (test 3a)"); - ret = http_stream_parse_chunk_header(str3, len3, FALSE, &chunklen); - UCX_TEST_ASSERT(ret == -1, "ret != -1 (test 3b)"); - - ret = http_stream_parse_chunk_header(str4, len4, TRUE, &chunklen); - UCX_TEST_ASSERT(ret == -1, "ret != -1 (test 4a)"); - ret = http_stream_parse_chunk_header(str4, len4, FALSE, &chunklen); - UCX_TEST_ASSERT(ret == -1, "ret != -1 (test 4b)"); - - ret = http_stream_parse_chunk_header(str5, len5, TRUE, &chunklen); - UCX_TEST_ASSERT(ret == -1, "ret != -1 (test 5a)"); - ret = http_stream_parse_chunk_header(str5, len5, FALSE, &chunklen); - UCX_TEST_ASSERT(ret == -1, "ret != -1 (test 5b)"); - - ret = http_stream_parse_chunk_header(str6, len6, TRUE, &chunklen); - UCX_TEST_ASSERT(ret == -1, "ret != -1 (test 6a)"); - ret = http_stream_parse_chunk_header(str6, len6, FALSE, &chunklen); - UCX_TEST_ASSERT(ret == -1, "ret != -1 (test 6b)"); - - UCX_TEST_END; free(str); free(str2); free(str3); @@ -230,7 +229,7 @@ free(str6); } -UCX_TEST(test_io_http_stream_parse_chunk_header_zero) { +CX_TEST(test_io_http_stream_parse_chunk_header_zero) { char *str = strdup("\r\n0\r\n\r\n"); size_t len = strlen(str); char *str2 = strdup("0\r\n\r\n"); @@ -243,26 +242,26 @@ size_t len4 = strlen(str4); - UCX_TEST_BEGIN; + CX_TEST_DO { - int64_t chunklen = -1; - int ret = http_stream_parse_chunk_header(str, len, FALSE, &chunklen); - UCX_TEST_ASSERT(ret == 7, "ret != 7"); - UCX_TEST_ASSERT(chunklen == 0, "chunklen != 0"); + int64_t chunklen = -1; + int ret = http_stream_parse_chunk_header(str, len, FALSE, &chunklen); + CX_TEST_ASSERT(ret == 7); + CX_TEST_ASSERT(chunklen == 0); + + chunklen = -1; + ret = http_stream_parse_chunk_header(str2, len2, TRUE, &chunklen); + CX_TEST_ASSERT(ret == 5); + CX_TEST_ASSERT(chunklen == 0); + + // expect 0 (incomplete) + ret = http_stream_parse_chunk_header(str3, len3, FALSE, &chunklen); + CX_TEST_ASSERT(ret == 0); + + ret = http_stream_parse_chunk_header(str4, len4, FALSE, &chunklen); + CX_TEST_ASSERT(ret == 0); - chunklen = -1; - ret = http_stream_parse_chunk_header(str2, len2, TRUE, &chunklen); - UCX_TEST_ASSERT(ret == 5, "ret != 5 (test 2)"); - UCX_TEST_ASSERT(chunklen == 0, "chunklen != 0 (test 2)"); - - // expect 0 (incomplete) - ret = http_stream_parse_chunk_header(str3, len3, FALSE, &chunklen); - UCX_TEST_ASSERT(ret == 0, "ret != 3 (test 3)"); - - ret = http_stream_parse_chunk_header(str4, len4, FALSE, &chunklen); - UCX_TEST_ASSERT(ret == 0, "ret != 3 (test 4)"); - - UCX_TEST_END; + } free(str); free(str2); free(str3); @@ -270,104 +269,102 @@ } -UCX_TEST(test_io_httpstream_write) { +CX_TEST(test_io_httpstream_write) { Session *sn = testutil_session(); TestIOStream *st = testutil_iostream(2048, TRUE); IOStream *http = httpstream_new(sn->pool, (IOStream*)st); - UCX_TEST_BEGIN; - - char *msg = "hello world!"; - size_t msglen = strlen(msg); - - ssize_t w = net_write(http, msg, msglen); - - UCX_TEST_ASSERT(w == msglen, "wrong size returned by net_write"); - UCX_TEST_ASSERT(st->buf->size == msglen, "wrong buffer size"); - UCX_TEST_ASSERT(!memcmp(st->buf->space, msg, msglen), "wrong buffer content"); + CX_TEST_DO { - // test again, make sure the second message is written directly after the wirst one - char *msg2 = "test"; - size_t msglen2 = strlen(msg2); - - w = net_write(http, msg2, msglen2); + char *msg = "hello world!"; + size_t msglen = strlen(msg); + + ssize_t w = net_write(http, msg, msglen); + + CX_TEST_ASSERT(w == msglen); + CX_TEST_ASSERT(st->buf->size == msglen); + CX_TEST_ASSERT(!memcmp(st->buf->space, msg, msglen)); + + // test again, make sure the second message is written directly after the wirst one + char *msg2 = "test"; + size_t msglen2 = strlen(msg2); + + w = net_write(http, msg2, msglen2); + + CX_TEST_ASSERT(w == msglen2); + CX_TEST_ASSERT(st->buf->size == msglen+msglen2); + CX_TEST_ASSERT(!memcmp(st->buf->space + msglen, msg2, msglen2)); - UCX_TEST_ASSERT(w == msglen2, "wrong size returned by net_write (2)"); - UCX_TEST_ASSERT(st->buf->size == msglen+msglen2, "wrong buffer size (2)"); - UCX_TEST_ASSERT(!memcmp(st->buf->space + msglen, msg2, msglen2), "wrong buffer content (2)"); - - UCX_TEST_END; + } testutil_destroy_session(sn); } -UCX_TEST(test_io_httpstream_chunked_write) { +CX_TEST(test_io_httpstream_chunked_write) { Session *sn = testutil_session(); TestIOStream *st = testutil_iostream(2048, TRUE); IOStream *http = httpstream_new(sn->pool, (IOStream*)st); httpstream_enable_chunked_write(http); - UCX_TEST_BEGIN; - - char *msg = "hello world!"; - size_t msglen = strlen(msg); - - char *bufmsg = "c\r\nhello world!\r\n"; - size_t bufmsglen = strlen(bufmsg); - - ssize_t w = net_write(http, msg, msglen); - - cxstring s1 = cx_strn(st->buf->space, st->buf->size); - cxstring s2 = cx_strn(bufmsg, bufmsglen); + CX_TEST_DO { - UCX_TEST_ASSERT(w == msglen, "wrong size returned by net_write"); - UCX_TEST_ASSERT(st->buf->size == bufmsglen, "wrong buffer size"); - UCX_TEST_ASSERT(!cx_strcasecmp(s1, s2), "wrong buffer content"); + char *msg = "hello world!"; + size_t msglen = strlen(msg); + + char *bufmsg = "c\r\nhello world!\r\n"; + size_t bufmsglen = strlen(bufmsg); + + ssize_t w = net_write(http, msg, msglen); + + cxstring s1 = cx_strn(st->buf->space, st->buf->size); + cxstring s2 = cx_strn(bufmsg, bufmsglen); + + CX_TEST_ASSERT(w == msglen); + CX_TEST_ASSERT(st->buf->size == bufmsglen); + CX_TEST_ASSERT(!cx_strcasecmp(s1, s2)); + + // write again + w = net_write(http, msg, msglen); + CX_TEST_ASSERT(w == msglen); + CX_TEST_ASSERT(st->buf->size == 2*bufmsglen); + + cxstring s3 = cx_strn(st->buf->space+bufmsglen, bufmsglen); + CX_TEST_ASSERT(!cx_strcasecmp(s2, s3)); - // write again - w = net_write(http, msg, msglen); - UCX_TEST_ASSERT(w == msglen, "write 2: wrong return value"); - UCX_TEST_ASSERT(st->buf->size == 2*bufmsglen, "write 2: wrong buf size"); - - cxstring s3 = cx_strn(st->buf->space+bufmsglen, bufmsglen); - UCX_TEST_ASSERT(!cx_strcasecmp(s2, s3), "write 2: wrong buf content"); - - - UCX_TEST_END; + } } -UCX_TEST(test_io_httpstream_chunked_write_end) { +CX_TEST(test_io_httpstream_chunked_write_end) { Session *sn = testutil_session(); TestIOStream *st = testutil_iostream(2048, TRUE); IOStream *http = httpstream_new(sn->pool, (IOStream*)st); httpstream_enable_chunked_write(http); - UCX_TEST_BEGIN; - - char *msg = "hello world!"; - size_t msglen = strlen(msg); - - char *bufmsg = "c\r\nhello world!\r\n0\r\n\r\n"; - size_t bufmsglen = strlen(bufmsg); + CX_TEST_DO { - ssize_t w = net_write(http, msg, msglen); - net_finish(http); - - cxstring s1 = cx_strn(st->buf->space, st->buf->size); - cxstring s2 = cx_strn(bufmsg, bufmsglen); + char *msg = "hello world!"; + size_t msglen = strlen(msg); + + char *bufmsg = "c\r\nhello world!\r\n0\r\n\r\n"; + size_t bufmsglen = strlen(bufmsg); + + ssize_t w = net_write(http, msg, msglen); + net_finish(http); + + cxstring s1 = cx_strn(st->buf->space, st->buf->size); + cxstring s2 = cx_strn(bufmsg, bufmsglen); + + CX_TEST_ASSERT(w == msglen); + CX_TEST_ASSERT(st->buf->size == bufmsglen); + CX_TEST_ASSERT(!cx_strcasecmp(s1, s2)); - UCX_TEST_ASSERT(w == msglen, "wrong size returned by net_write"); - UCX_TEST_ASSERT(st->buf->size == bufmsglen, "wrong buffer size"); - UCX_TEST_ASSERT(!cx_strcasecmp(s1, s2), "wrong buffer content"); - - - UCX_TEST_END; + } } -UCX_TEST(test_io_httpstream_chunked_write_xx) { +CX_TEST(test_io_httpstream_chunked_write_xx) { // This test creates a giant buffer and writes it with // chunked transfer encoding to the http stream with varying chunk length @@ -377,91 +374,91 @@ IOStream *http = httpstream_new(sn->pool, (IOStream*)st); httpstream_enable_chunked_write(http); - UCX_TEST_BEGIN; - - // create test data - CxBuffer *testdata = cxBufferCreate(NULL, 1024*1024*4, cxDefaultAllocator, 0); - for(size_t i=0;i<testdata->capacity;i++) { - cxBufferPut(testdata, 35+(i%91)); - } - - // write chunks, start with single diget chunk length and increase - // chunk size with each step - size_t pos = 0; - int j = 0; - ssize_t i=15; - while(pos<testdata->size) { - char *buf = testdata->space + pos; - size_t remaining = testdata->size - pos; - ssize_t len = pos + i < remaining ? i : remaining; - pos += len; - - ssize_t w = net_write(http, buf, len); - - UCX_TEST_ASSERT(w == len, "wrong size returned by net_write"); - i+=100; // increase chunk size - j++; // debug - } - - // terminate chunk - net_finish(http); - - // code below also used in test_io_httpstream_chunked_write_xx_limit - - // make sure the output is correctly encoded - // extract chunks from st->buf by using http_stream_parse_chunk_header - // (which should be well-tested) - WSBool first_chunk = TRUE; - int64_t chunklen = 0; + CX_TEST_DO { - char *buf = st->buf->space; - size_t bufsize = st->buf->size; - - pos = 0; // st->buf position - size_t srcpos = 0; // testdata position - int debug_counter = 0; - while(pos < bufsize) { - ssize_t remaining = bufsize - pos; - ssize_t src_remaining = testdata->size - srcpos; - - int ret = http_stream_parse_chunk_header(buf+pos, remaining, first_chunk, &chunklen); - first_chunk = FALSE; - - // ret must always be > 0 (0: incomplete chunk header, -1: invalid syntax) - UCX_TEST_ASSERT(ret > 0, "http_stream_parse_chunk_header ret <= 0"); - if(chunklen == 0) { - UCX_TEST_ASSERT(src_remaining == 0, "stream end reached but src_remaining > 0"); - break; + // create test data + CxBuffer *testdata = cxBufferCreate(NULL, 1024*1024*4, cxDefaultAllocator, 0); + for(size_t i=0;i<testdata->capacity;i++) { + cxBufferPut(testdata, 35+(i%91)); + } + + // write chunks, start with single diget chunk length and increase + // chunk size with each step + size_t pos = 0; + int j = 0; + ssize_t i=15; + while(pos<testdata->size) { + char *buf = testdata->space + pos; + size_t remaining = testdata->size - pos; + ssize_t len = pos + i < remaining ? i : remaining; + pos += len; + + ssize_t w = net_write(http, buf, len); + + CX_TEST_ASSERT(w == len); + i+=100; // increase chunk size + j++; // debug } - - UCX_TEST_ASSERT(chunklen <= src_remaining, "chunklen > src_remaining"); - - char *src_chunk = testdata->space+srcpos; - char *buf_chunk = buf+pos+ret; - - UCX_TEST_ASSERT(!memcmp(buf_chunk, src_chunk, chunklen), "memcmp failed"); - - pos += ret + chunklen; - srcpos += chunklen; - - debug_counter++; + + // terminate chunk + net_finish(http); + + // code below also used in test_io_httpstream_chunked_write_xx_limit + + // make sure the output is correctly encoded + // extract chunks from st->buf by using http_stream_parse_chunk_header + // (which should be well-tested) + WSBool first_chunk = TRUE; + int64_t chunklen = 0; + + char *buf = st->buf->space; + size_t bufsize = st->buf->size; + + pos = 0; // st->buf position + size_t srcpos = 0; // testdata position + int debug_counter = 0; + while(pos < bufsize) { + ssize_t remaining = bufsize - pos; + ssize_t src_remaining = testdata->size - srcpos; + + int ret = http_stream_parse_chunk_header(buf+pos, remaining, first_chunk, &chunklen); + first_chunk = FALSE; + + // ret must always be > 0 (0: incomplete chunk header, -1: invalid syntax) + CX_TEST_ASSERT(ret > 0); + if(chunklen == 0) { + CX_TEST_ASSERT(src_remaining == 0); + break; + } + + CX_TEST_ASSERT(chunklen <= src_remaining); + + char *src_chunk = testdata->space+srcpos; + char *buf_chunk = buf+pos+ret; + + CX_TEST_ASSERT(!memcmp(buf_chunk, src_chunk, chunklen)); + + pos += ret + chunklen; + srcpos += chunklen; + + debug_counter++; + } + + cxBufferFree(testdata); + testutil_destroy_session(sn); + testutil_iostream_destroy(st); + } - - cxBufferFree(testdata); - testutil_destroy_session(sn); - testutil_iostream_destroy(st); - - UCX_TEST_END; } -UCX_TEST(test_io_httpstream_chunked_write_partial_header) { +CX_TEST(test_io_httpstream_chunked_write_partial_header) { Session *sn = testutil_session(); TestIOStream *st = testutil_iostream(2048, TRUE); IOStream *http = httpstream_new(sn->pool, (IOStream*)st); httpstream_enable_chunked_write(http); - UCX_TEST_BEGIN; + CX_TEST_DO { memset(st->buf->space, 0, st->buf->capacity); @@ -473,89 +470,89 @@ // only 1 byte of the header is written, 0 bytes of msg ssize_t w = net_write(http, msg, msglen); - UCX_TEST_ASSERT(w == 0, "write 1: wrong return value"); - UCX_TEST_ASSERT(st->buf->size == 1, "write 1: wrong buf size"); - UCX_TEST_ASSERT(tolower(st->buf->space[0]) == 'c', "write 1: wrong buf content"); + CX_TEST_ASSERT(w == 0); + CX_TEST_ASSERT(st->buf->size == 1); + CX_TEST_ASSERT(tolower(st->buf->space[0]) == 'c'); // next header byte: '\r' w = net_write(http, msg, msglen); - UCX_TEST_ASSERT(w == 0, "write 2: wrong return value"); - UCX_TEST_ASSERT(st->buf->size == 2, "write 2: wrong buf size"); - UCX_TEST_ASSERT(st->buf->space[1] == '\r', "write 2: wrong content"); + CX_TEST_ASSERT(w == 0); + CX_TEST_ASSERT(st->buf->size == 2); + CX_TEST_ASSERT(st->buf->space[1] == '\r'); // next header byte: '\n' w = net_write(http, msg, msglen); - UCX_TEST_ASSERT(w == 0, "write 3: wrong return value"); - UCX_TEST_ASSERT(st->buf->size == 3, "write 3: wrong buf size"); - UCX_TEST_ASSERT(st->buf->space[2] == '\n', "write 3: wrong content"); + CX_TEST_ASSERT(w == 0); + CX_TEST_ASSERT(st->buf->size == 3); + CX_TEST_ASSERT(st->buf->space[2] == '\n'); // next: content w = net_write(http, msg, msglen); - UCX_TEST_ASSERT(w == 1, "write 4: wrong return value"); - UCX_TEST_ASSERT(st->buf->size == 4, "write 3: wrong buf size"); - UCX_TEST_ASSERT(st->buf->space[3] == msg[0], "write 3: wrong content"); + CX_TEST_ASSERT(w == 1); + CX_TEST_ASSERT(st->buf->size == 4); + CX_TEST_ASSERT(st->buf->space[3] == msg[0]); testutil_destroy_session(sn); testutil_iostream_destroy(st); - UCX_TEST_END; + } } -UCX_TEST(test_io_httpstream_chunked_write_partial_data) { +CX_TEST(test_io_httpstream_chunked_write_partial_data) { Session *sn = testutil_session(); TestIOStream *st = testutil_iostream(2048, TRUE); IOStream *http = httpstream_new(sn->pool, (IOStream*)st); httpstream_enable_chunked_write(http); - UCX_TEST_BEGIN; - - memset(st->buf->space, 0, st->buf->capacity); - - char *msg = "hello world!"; - size_t msglen = strlen(msg); - size_t msglen_orig = msglen; - - // limit first write to 3 to only write the header - st->max_write = 3; - io_set_max_writes(1); - - ssize_t w = net_write(http, msg, msglen); - - UCX_TEST_ASSERT(w == 0, "write 1: wrong return value"); - UCX_TEST_ASSERT(st->buf->size == 3, "write 1: wrong buf size"); - UCX_TEST_ASSERT(st->buf->space[0] == 'c', "write 1: wrong buf content"); - UCX_TEST_ASSERT(st->buf->space[2] == '\n', "write 1: wrong buf content"); + CX_TEST_DO { - w = net_write(http, msg, msglen); - UCX_TEST_ASSERT(w == 3, "write 2: wrong return value"); - UCX_TEST_ASSERT(st->buf->size == 6, "write 2: wrong buf size"); - UCX_TEST_ASSERT(!memcmp(st->buf->space, "c\r\nhel\0", 7), "write 2: wrong buf content"); - - msg += w; - msglen -= w; - - w = net_write(http, msg, msglen); - UCX_TEST_ASSERT(w == 3, "write 3: wrong return value"); - UCX_TEST_ASSERT(st->buf->size == 9, "write 3: wrong buf size"); - UCX_TEST_ASSERT(!memcmp(st->buf->space, "c\r\nhello \0", 10), "write 3: wrong buf content"); + memset(st->buf->space, 0, st->buf->capacity); + + char *msg = "hello world!"; + size_t msglen = strlen(msg); + size_t msglen_orig = msglen; + + // limit first write to 3 to only write the header + st->max_write = 3; + io_set_max_writes(1); + + ssize_t w = net_write(http, msg, msglen); + + CX_TEST_ASSERT(w == 0); + CX_TEST_ASSERT(st->buf->size == 3); + CX_TEST_ASSERT(st->buf->space[0] == 'c'); + CX_TEST_ASSERT(st->buf->space[2] == '\n'); + + w = net_write(http, msg, msglen); + CX_TEST_ASSERT(w == 3); + CX_TEST_ASSERT(st->buf->size == 6); + CX_TEST_ASSERT(!memcmp(st->buf->space, "c\r\nhel\0", 7)); + + msg += w; + msglen -= w; + + w = net_write(http, msg, msglen); + CX_TEST_ASSERT(w == 3); + CX_TEST_ASSERT(st->buf->size == 9); + CX_TEST_ASSERT(!memcmp(st->buf->space, "c\r\nhello \0", 10)); + + st->max_write = 1024; + msg += w; + msglen -= w; + + w = net_write(http, msg, msglen); + CX_TEST_ASSERT(w == msglen); + CX_TEST_ASSERT(st->buf->size == 3 + msglen_orig + 2); + CX_TEST_ASSERT(!memcmp(st->buf->space, "c\r\nhello world!\r\n", st->buf->size)); + + testutil_destroy_session(sn); + testutil_iostream_destroy(st); - st->max_write = 1024; - msg += w; - msglen -= w; - - w = net_write(http, msg, msglen); - UCX_TEST_ASSERT(w == msglen, "write 4: wrong return value"); - UCX_TEST_ASSERT(st->buf->size == 3 + msglen_orig + 2, "write 4: wrong buf size"); - UCX_TEST_ASSERT(!memcmp(st->buf->space, "c\r\nhello world!\r\n", st->buf->size), "write 4: wrong buf content"); - - testutil_destroy_session(sn); - testutil_iostream_destroy(st); - - UCX_TEST_END; + } } -UCX_TEST(test_io_httpstream_chunked_write_partial_trailer) { +CX_TEST(test_io_httpstream_chunked_write_partial_trailer) { Session *sn = testutil_session(); TestIOStream *st = testutil_iostream(2048, TRUE); @@ -563,60 +560,60 @@ httpstream_enable_chunked_write(http); io_set_max_writes(1); - UCX_TEST_BEGIN; - - memset(st->buf->space, 0, st->buf->capacity); - - char *msg = "hello world!"; - size_t msglen = strlen(msg); - - char *msg2 = "newmsg"; - size_t msglen2 = strlen(msg2); - - char *msg3 = "msg3"; - size_t msglen3 = strlen(msg3); - - st->max_write = 3 + msglen; // header + msg, but without trailer - - ssize_t w = net_write(http, msg, msglen); - - UCX_TEST_ASSERT(w == msglen, "write 1: wrong return value"); - UCX_TEST_ASSERT(st->buf->size == 3 + msglen, "write 1: wrong buf size"); - UCX_TEST_ASSERT(!memcmp(st->buf->space, "c\r\nhello world!\0", st->buf->size + 1), "write 1: wrong buf content"); - - st->max_write = 2 + 3 + msglen2; // trailer + new header + new msg, without new trailer + CX_TEST_DO { - w = net_write(http, msg2, msglen2); - UCX_TEST_ASSERT(w == msglen2, "write 2: wrong return value"); - UCX_TEST_ASSERT(st->buf->size == 3 + msglen + 2 + 3 + msglen2, "write 2: wrong buf size"); - 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"); - - // limit write to 1 byte: two writes required for trailer, net_write should return 0 - st->max_write = 1; - - w = net_write(http, "dummymsg", 8); - UCX_TEST_ASSERT(w == 0, "write 3: wrong return value"); + memset(st->buf->space, 0, st->buf->capacity); + + char *msg = "hello world!"; + size_t msglen = strlen(msg); + + char *msg2 = "newmsg"; + size_t msglen2 = strlen(msg2); + + char *msg3 = "msg3"; + size_t msglen3 = strlen(msg3); + + st->max_write = 3 + msglen; // header + msg, but without trailer + + ssize_t w = net_write(http, msg, msglen); + + CX_TEST_ASSERT(w == msglen); + CX_TEST_ASSERT(st->buf->size == 3 + msglen); + CX_TEST_ASSERT(!memcmp(st->buf->space, "c\r\nhello world!\0", st->buf->size + 1)); + + st->max_write = 2 + 3 + msglen2; // trailer + new header + new msg, without new trailer + + w = net_write(http, msg2, msglen2); + CX_TEST_ASSERT(w == msglen2); + CX_TEST_ASSERT(st->buf->size == 3 + msglen + 2 + 3 + msglen2); + CX_TEST_ASSERT(!memcmp(st->buf->space, "c\r\nhello world!\r\n6\r\nnewmsg\0", st->buf->size + 1)); + + // limit write to 1 byte: two writes required for trailer, net_write should return 0 + st->max_write = 1; + + w = net_write(http, "dummymsg", 8); + CX_TEST_ASSERT(w == 0); + + w = net_write(http, "dummymsg", 8); + CX_TEST_ASSERT(w == 0); + CX_TEST_ASSERT(st->buf->size == 3 + msglen + 2 + 3 + msglen2 + 2); + CX_TEST_ASSERT(!memcmp(st->buf->space, "c\r\nhello world!\r\n6\r\nnewmsg\r\n\0", st->buf->size + 1)); + + st->max_write = 1024; + w = net_write(http, msg3, msglen3); + + CX_TEST_ASSERT(w == msglen3); + CX_TEST_ASSERT(st->buf->size == 3 + msglen + 2 + 3 + msglen2 + 2 + 3 + msglen3 + 2); + CX_TEST_ASSERT(!memcmp(st->buf->space, "c\r\nhello world!\r\n6\r\nnewmsg\r\n4\r\nmsg3\r\n", st->buf->size + 1)); + + + testutil_destroy_session(sn); + testutil_iostream_destroy(st); - w = net_write(http, "dummymsg", 8); - UCX_TEST_ASSERT(w == 0, "write 4: wrong return value"); - UCX_TEST_ASSERT(st->buf->size == 3 + msglen + 2 + 3 + msglen2 + 2, "write 4: wrong buf size"); - 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"); - - st->max_write = 1024; - w = net_write(http, msg3, msglen3); - - UCX_TEST_ASSERT(w == msglen3, "write 5: wrong return value"); - UCX_TEST_ASSERT(st->buf->size == 3 + msglen + 2 + 3 + msglen2 + 2 + 3 + msglen3 + 2, "write 5: wrong buf size"); - 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"); - - - testutil_destroy_session(sn); - testutil_iostream_destroy(st); - - UCX_TEST_END; + } } -UCX_TEST(test_io_httpstream_chunked_write_partial_trailer_partial_header) { +CX_TEST(test_io_httpstream_chunked_write_partial_trailer_partial_header) { Session *sn = testutil_session(); TestIOStream *st = testutil_iostream(2048, TRUE); @@ -624,59 +621,59 @@ httpstream_enable_chunked_write(http); io_set_max_writes(1); - UCX_TEST_BEGIN; - - memset(st->buf->space, 0, st->buf->capacity); - - char *msg = "hello world!"; - size_t msglen = strlen(msg); - - char *msg2 = "newmsg"; - size_t msglen2 = strlen(msg2); - - // Test: write partial trailer followed by partial header write - - st->max_write = 3 + msglen + 1; - - ssize_t w = net_write(http, msg, msglen); - - UCX_TEST_ASSERT(w == msglen, "write 1: wrong return value"); - UCX_TEST_ASSERT(st->buf->size == 3 + msglen + 1, "write 1: wrong buf size"); - UCX_TEST_ASSERT(!memcmp(st->buf->space, "c\r\nhello world!\r\0", st->buf->size + 1), "write 1: wrong buf content"); - - st->max_write = 2; // write 1 trailer byte and 1 header byte - - w = net_write(http, msg2, msglen2); + CX_TEST_DO { - UCX_TEST_ASSERT(w == 0, "write 2: wrong return value"); - UCX_TEST_ASSERT(st->buf->size == 3 + msglen + 2 + 1, "write 2: wrong buf size"); - UCX_TEST_ASSERT(!memcmp(st->buf->space, "c\r\nhello world!\r\n6\0", st->buf->size + 1), "write 2: wrong buf content"); - - // force partial header write again - st->max_write = 1; - - w = net_write(http, msg2, msglen2); - - UCX_TEST_ASSERT(w == 0, "write 3: wrong return value"); - UCX_TEST_ASSERT(st->buf->size == 3 + msglen + 2 + 2, "write 3: wrong buf size"); - UCX_TEST_ASSERT(!memcmp(st->buf->space, "c\r\nhello world!\r\n6\r\0", st->buf->size + 1), "write 3: wrong buf content"); + memset(st->buf->space, 0, st->buf->capacity); + + char *msg = "hello world!"; + size_t msglen = strlen(msg); + + char *msg2 = "newmsg"; + size_t msglen2 = strlen(msg2); + + // Test: write partial trailer followed by partial header write + + st->max_write = 3 + msglen + 1; + + ssize_t w = net_write(http, msg, msglen); + + CX_TEST_ASSERT(w == msglen); + CX_TEST_ASSERT(st->buf->size == 3 + msglen + 1); + CX_TEST_ASSERT(!memcmp(st->buf->space, "c\r\nhello world!\r\0", st->buf->size + 1)); + + st->max_write = 2; // write 1 trailer byte and 1 header byte + + w = net_write(http, msg2, msglen2); + + CX_TEST_ASSERT(w == 0); + CX_TEST_ASSERT(st->buf->size == 3 + msglen + 2 + 1); + CX_TEST_ASSERT(!memcmp(st->buf->space, "c\r\nhello world!\r\n6\0", st->buf->size + 1)); + + // force partial header write again + st->max_write = 1; + + w = net_write(http, msg2, msglen2); + + CX_TEST_ASSERT(w == 0); + CX_TEST_ASSERT(st->buf->size == 3 + msglen + 2 + 2); + CX_TEST_ASSERT(!memcmp(st->buf->space, "c\r\nhello world!\r\n6\r\0", st->buf->size + 1)); + + st->max_write = 1024; + + w = net_write(http, msg2, msglen2); + + CX_TEST_ASSERT(w ==msglen2); + CX_TEST_ASSERT(st->buf->size == 3 + msglen + 2 + 3 + msglen2 + 2); + CX_TEST_ASSERT(!memcmp(st->buf->space, "c\r\nhello world!\r\n6\r\nnewmsg\r\n", st->buf->size + 1)); + + + testutil_destroy_session(sn); + testutil_iostream_destroy(st); - st->max_write = 1024; - - w = net_write(http, msg2, msglen2); - - UCX_TEST_ASSERT(w ==msglen2, "write 4: wrong return value"); - UCX_TEST_ASSERT(st->buf->size == 3 + msglen + 2 + 3 + msglen2 + 2, "write 4: wrong buf size"); - 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"); - - - testutil_destroy_session(sn); - testutil_iostream_destroy(st); - - UCX_TEST_END; + } } -UCX_TEST(test_io_httpstream_chunked_write_data_2x) { +CX_TEST(test_io_httpstream_chunked_write_data_2x) { Session *sn = testutil_session(); TestIOStream *st = testutil_iostream(2048, TRUE); @@ -684,46 +681,46 @@ httpstream_enable_chunked_write(http); io_set_max_writes(1); - UCX_TEST_BEGIN; - - memset(st->buf->space, 0, st->buf->capacity); - - // Test: First write a partial header, which forces a chunk with a specific - // size. After that, write a message, that is bigger than the first - // chunk, forcing a start of a second chunk, in one big writev op. - - char *msg = "hello world!"; - size_t msglen = strlen(msg); - - char *msg2 = "newmsg"; - size_t msglen2 = strlen(msg2); - - char *msg_big = "hello world!newmsg"; - size_t msglen_big = strlen(msg_big); - - st->max_write = 1; + CX_TEST_DO { - ssize_t w = net_write(http, msg, msglen); // first chunk: msg - - UCX_TEST_ASSERT(w == 0, "write 1: wrong return value"); - UCX_TEST_ASSERT(st->buf->size == 1, "write 1: wrong buf size"); - - st->max_write = 1024; - - w = net_write(http, msg_big, msglen_big); // first chunk + new chunk + memset(st->buf->space, 0, st->buf->capacity); + + // Test: First write a partial header, which forces a chunk with a specific + // size. After that, write a message, that is bigger than the first + // chunk, forcing a start of a second chunk, in one big writev op. + + char *msg = "hello world!"; + size_t msglen = strlen(msg); + + char *msg2 = "newmsg"; + size_t msglen2 = strlen(msg2); + + char *msg_big = "hello world!newmsg"; + size_t msglen_big = strlen(msg_big); + + st->max_write = 1; + + ssize_t w = net_write(http, msg, msglen); // first chunk: msg + + CX_TEST_ASSERT(w == 0); + CX_TEST_ASSERT(st->buf->size == 1); + + st->max_write = 1024; + + w = net_write(http, msg_big, msglen_big); // first chunk + new chunk + + CX_TEST_ASSERT(w == msglen_big); + CX_TEST_ASSERT(st->buf->size == 3 + msglen + 2 + 3 + msglen2 + 2); + CX_TEST_ASSERT(!memcmp(st->buf->space, "c\r\nhello world!\r\n6\r\nnewmsg\r\n", st->buf->size + 1)); + + + testutil_destroy_session(sn); + testutil_iostream_destroy(st); - UCX_TEST_ASSERT(w == msglen_big, "write 2: wrong return value"); - UCX_TEST_ASSERT(st->buf->size == 3 + msglen + 2 + 3 + msglen2 + 2, "write 2: wrong buf size"); - 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"); - - - testutil_destroy_session(sn); - testutil_iostream_destroy(st); - - UCX_TEST_END; + } } -UCX_TEST(test_io_httpstream_chunked_write_xx_limit) { +CX_TEST(test_io_httpstream_chunked_write_xx_limit) { Session *sn = testutil_session(); TestIOStream *st = testutil_iostream(2048, TRUE); @@ -731,105 +728,105 @@ httpstream_enable_chunked_write(http); io_set_max_writes(1); - UCX_TEST_BEGIN; - - // Test: create testdata and write it in varying chunk sizes, but - // limit TestIOStream to 1 to 3 byte writes - - // create test data - CxBuffer *testdata = cxBufferCreate(NULL, 1024*16, cxDefaultAllocator, 0); - for(size_t i=0;i<testdata->capacity;i++) { - cxBufferPut(testdata, 35+(i%91)); - } - - st->max_write = 1; + CX_TEST_DO { - size_t pos = 0; - int chunksize = 1; - while(pos < testdata->size) { - size_t available = testdata->size - pos; - - char *chunk = testdata->space + pos; - size_t chunklen = chunksize > available ? available : chunksize; - - // write chunk - size_t chunkpos = 0; - int max_writes = chunklen + 24; // max number of write attempts - int writes = 0; - while(chunkpos < chunklen) { - ssize_t w = net_write(http, chunk+chunkpos, chunklen-chunkpos); - UCX_TEST_ASSERT(w >= 0, "net_write failed"); - chunkpos += w; - - writes++; - UCX_TEST_ASSERT(writes < max_writes, "max writes attempts reached"); + // Test: create testdata and write it in varying chunk sizes, but + // limit TestIOStream to 1 to 3 byte writes + + // create test data + CxBuffer *testdata = cxBufferCreate(NULL, 1024*16, cxDefaultAllocator, 0); + for(size_t i=0;i<testdata->capacity;i++) { + cxBufferPut(testdata, 35+(i%91)); } - - pos += chunklen; - chunksize += 5; - - // increase max write size at some point - if(pos + chunksize >= testdata->size) { - st->max_write = INT_MAX; - } else if(pos > 1024*2) { - if(pos < 1024*8) { - st->max_write = 2; - } else { - st->max_write = 3; + + st->max_write = 1; + + size_t pos = 0; + int chunksize = 1; + while(pos < testdata->size) { + size_t available = testdata->size - pos; + + char *chunk = testdata->space + pos; + size_t chunklen = chunksize > available ? available : chunksize; + + // write chunk + size_t chunkpos = 0; + int max_writes = chunklen + 24; // max number of write attempts + int writes = 0; + while(chunkpos < chunklen) { + ssize_t w = net_write(http, chunk+chunkpos, chunklen-chunkpos); + CX_TEST_ASSERT(w >= 0); + chunkpos += w; + + writes++; + CX_TEST_ASSERT(writes < max_writes); + } + + pos += chunklen; + chunksize += 5; + + // increase max write size at some point + if(pos + chunksize >= testdata->size) { + st->max_write = INT_MAX; + } else if(pos > 1024*2) { + if(pos < 1024*8) { + st->max_write = 2; + } else { + st->max_write = 3; + } } } - } - - // terminate chunk - net_finish(http); - - - // same code as test_io_httpstream_chunked_write_xx - - // make sure the output is correctly encoded - // extract chunks from st->buf by using http_stream_parse_chunk_header - // (which should be well-tested) - - WSBool first_chunk = TRUE; - int64_t chunklen = 0; - - char *buf = st->buf->space; - size_t bufsize = st->buf->size; + + // terminate chunk + net_finish(http); + + + // same code as test_io_httpstream_chunked_write_xx + + // make sure the output is correctly encoded + // extract chunks from st->buf by using http_stream_parse_chunk_header + // (which should be well-tested) + + WSBool first_chunk = TRUE; + int64_t chunklen = 0; + + char *buf = st->buf->space; + size_t bufsize = st->buf->size; + + pos = 0; // st->buf position + size_t srcpos = 0; // testdata position + int debug_counter = 0; + while(pos < bufsize) { + ssize_t remaining = bufsize - pos; + ssize_t src_remaining = testdata->size - srcpos; + + int ret = http_stream_parse_chunk_header(buf+pos, remaining, first_chunk, &chunklen); + first_chunk = FALSE; + + // ret must always be > 0 (0: incomplete chunk header, -1: invalid syntax) + CX_TEST_ASSERT(ret > 0); + if(chunklen == 0) { + CX_TEST_ASSERT(src_remaining == 0); + break; + } + + CX_TEST_ASSERT(chunklen <= src_remaining); + + char *src_chunk = testdata->space+srcpos; + char *buf_chunk = buf+pos+ret; + + CX_TEST_ASSERT(!memcmp(buf_chunk, src_chunk, chunklen)); + + pos += ret + chunklen; + srcpos += chunklen; + + debug_counter++; + } + + + testutil_destroy_session(sn); + testutil_iostream_destroy(st); + cxBufferFree(testdata); - pos = 0; // st->buf position - size_t srcpos = 0; // testdata position - int debug_counter = 0; - while(pos < bufsize) { - ssize_t remaining = bufsize - pos; - ssize_t src_remaining = testdata->size - srcpos; - - int ret = http_stream_parse_chunk_header(buf+pos, remaining, first_chunk, &chunklen); - first_chunk = FALSE; - - // ret must always be > 0 (0: incomplete chunk header, -1: invalid syntax) - UCX_TEST_ASSERT(ret > 0, "http_stream_parse_chunk_header ret <= 0"); - if(chunklen == 0) { - UCX_TEST_ASSERT(src_remaining == 0, "stream end reached but src_remaining > 0"); - break; - } - - UCX_TEST_ASSERT(chunklen <= src_remaining, "chunklen > src_remaining"); - - char *src_chunk = testdata->space+srcpos; - char *buf_chunk = buf+pos+ret; - - UCX_TEST_ASSERT(!memcmp(buf_chunk, src_chunk, chunklen), "memcmp failed"); - - pos += ret + chunklen; - srcpos += chunklen; - - debug_counter++; } - - - testutil_destroy_session(sn); - testutil_iostream_destroy(st); - cxBufferFree(testdata); - - UCX_TEST_END; }