#include "io.h"
#include "testutils.h"
UCX_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");
size_t len2 = strlen(str2);
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");
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)");
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)");
UCX_TEST_END;
free(str);
free(str2);
}
UCX_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");
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)");
UCX_TEST_END;
free(str);
free(str2);
}
UCX_TEST(test_io_http_stream_parse_chunk_header_hdronly_seq_fail) {
char *str = strdup(
"ff\r\n");
size_t len = strlen(str);
UCX_TEST_BEGIN;
int64_t chunklen;
int ret = http_stream_parse_chunk_header(str, len,
FALSE, &chunklen);
UCX_TEST_ASSERT(ret == -
1,
"ret != -1");
UCX_TEST_END;
free(str);
}
UCX_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;
int64_t chunklen;
int ret = http_stream_parse_chunk_header(str, len,
FALSE, &chunklen);
UCX_TEST_ASSERT(ret ==
5,
"ret != 5");
UCX_TEST_END;
free(str);
}
UCX_TEST(test_io_http_stream_parse_chunk_header_empty) {
char *str =
"";
size_t len = strlen(str);
UCX_TEST_BEGIN;
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)");
UCX_TEST_END;
}
UCX_TEST(test_io_http_stream_parse_chunk_header_partial_first) {
char *str = strdup(
"123");
size_t len = strlen(str);
UCX_TEST_BEGIN;
int64_t chunklen;
int ret = http_stream_parse_chunk_header(str, len,
TRUE, &chunklen);
UCX_TEST_ASSERT(ret ==
0,
"ret != 0");
UCX_TEST_END;
free(str);
}
UCX_TEST(test_io_http_stream_parse_chunk_header_partial) {
char *str = strdup(
"123");
size_t len = strlen(str);
char *str2 = strdup(
"\r\n");
size_t len2 = strlen(str2);
char *str3 = strdup(
"\r");
size_t len3 = strlen(str3);
char *str4 = strdup(
"\r\n123");
size_t len4 = strlen(str4);
UCX_TEST_BEGIN;
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");
UCX_TEST_END;
free(str);
free(str2);
free(str3);
free(str4);
}
UCX_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");
size_t len2 = strlen(str2);
char *str3 = strdup(
"\r\n\r\n123\r\n");
size_t len3 = strlen(str3);
char *str4 = strdup(
"\r\n\r\nx123\r\n");
size_t len4 = strlen(str3);
char *str5 = strdup(
"\r\n\r\n1 2 3\r\n");
size_t len5 = strlen(str3);
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)");
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);
free(str4);
free(str5);
free(str6);
}
UCX_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");
size_t len2 = strlen(str2);
char *str3 = strdup(
"\r\n0\r\n");
size_t len3 = strlen(str3);
char *str4 = strdup(
"\r\n0");
size_t len4 = strlen(str4);
UCX_TEST_BEGIN;
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");
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)");
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);
free(str4);
}
UCX_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");
char *msg2 =
"test";
size_t msglen2 = strlen(msg2);
w = net_write(http, 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) {
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);
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");
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) {
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);
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);
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) {
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;
CxBuffer *testdata = cxBufferCreate(
NULL,
1024*
1024*
4, cxDefaultAllocator,
0);
for(
size_t i=
0;i<testdata->capacity;i++) {
cxBufferPut(testdata,
35+(i%
91));
}
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;
j++;
}
net_finish(http);
WSBool first_chunk =
TRUE;
int64_t chunklen =
0;
char *buf = st->buf->space;
size_t bufsize = st->buf->size;
pos =
0;
size_t srcpos =
0;
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;
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++;
}
cxBufferFree(testdata);
testutil_destroy_session(sn);
testutil_iostream_destroy(st);
UCX_TEST_END;
}
UCX_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;
memset(st->buf->space,
0, st->buf->capacity);
char *msg =
"hello world!";
size_t msglen = strlen(msg);
st->max_write =
1;
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 ==
1,
"write 1: wrong buf size");
UCX_TEST_ASSERT(tolower(st->buf->space[
0]) ==
'c',
"write 1: wrong buf content");
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");
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");
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");
testutil_destroy_session(sn);
testutil_iostream_destroy(st);
UCX_TEST_END;
}
UCX_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;
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");
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");
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) {
Session *sn = testutil_session();
TestIOStream *st = testutil_iostream(
2048,
TRUE);
IOStream *http = httpstream_new(sn->pool, (IOStream*)st);
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;
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;
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");
st->max_write =
1;
w = net_write(http,
"dummymsg",
8);
UCX_TEST_ASSERT(w ==
0,
"write 3: wrong return value");
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) {
Session *sn = testutil_session();
TestIOStream *st = testutil_iostream(
2048,
TRUE);
IOStream *http = httpstream_new(sn->pool, (IOStream*)st);
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);
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;
w = net_write(http, msg2, msglen2);
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");
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");
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) {
Session *sn = testutil_session();
TestIOStream *st = testutil_iostream(
2048,
TRUE);
IOStream *http = httpstream_new(sn->pool, (IOStream*)st);
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 *msg_big =
"hello world!newmsg";
size_t msglen_big = strlen(msg_big);
st->max_write =
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 ==
1,
"write 1: wrong buf size");
st->max_write =
1024;
w = net_write(http, msg_big, msglen_big);
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) {
Session *sn = testutil_session();
TestIOStream *st = testutil_iostream(
2048,
TRUE);
IOStream *http = httpstream_new(sn->pool, (IOStream*)st);
httpstream_enable_chunked_write(http);
io_set_max_writes(
1);
UCX_TEST_BEGIN;
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;
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;
size_t chunkpos =
0;
int max_writes = chunklen +
24;
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");
}
pos += chunklen;
chunksize +=
5;
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;
}
}
}
net_finish(http);
WSBool first_chunk =
TRUE;
int64_t chunklen =
0;
char *buf = st->buf->space;
size_t bufsize = st->buf->size;
pos =
0;
size_t srcpos =
0;
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;
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;
}