Tue, 24 Feb 2026 21:28:06 +0100
add more httpclient tests
--- a/src/server/daemon/httpparser.c Tue Feb 24 12:28:58 2026 +0100 +++ b/src/server/daemon/httpparser.c Tue Feb 24 21:28:06 2026 +0100 @@ -70,6 +70,9 @@ int r = get_start_line(parser); switch(r) { case 0: break; + case 2: { + return r; + } default: return r; } if(parser->type == 0) { @@ -313,6 +316,10 @@ } } + if(parser->msg.length == 0) { + return 1; + } + return parser->msg.length == 0; }
--- a/src/server/proxy/httpclient.c Tue Feb 24 12:28:58 2026 +0100 +++ b/src/server/proxy/httpclient.c Tue Feb 24 21:28:06 2026 +0100 @@ -470,11 +470,11 @@ return 0; } - unsigned char *buffer = client->buffer.inbuf + client->buffer.pos; + unsigned char *buffer = client->buffer.inbuf + client->buffer.cursize; size_t nbytes = client->buffer.maxsize - client->buffer.cursize; - + ssize_t r; - while((r = read(client->socketfd, buffer, nbytes)) > 0) { + while((r = read(client->socketfd, buffer, nbytes)) > 0) { client->buffer.cursize += r; if(!client->response_header_complete) { switch(http_parser_process(client->parser)) {
--- a/src/server/test/httpclient.c Tue Feb 24 12:28:58 2026 +0100 +++ b/src/server/test/httpclient.c Tue Feb 24 21:28:06 2026 +0100 @@ -48,6 +48,7 @@ pthread_cond_signal(&test_cond); pthread_mutex_unlock(&test_mutex); http_client_free(client); + test_finished = 1; } static ssize_t test_response_body_write(HttpClient *client, void *buf, size_t nbytes, void *userdata) { @@ -55,7 +56,7 @@ return cxBufferWrite(buf, 1, nbytes, userdata); } -CX_TEST_SUBROUTINE(test_httpclient, cxstring response, CxBuffer *out, int response_blocksz, int error_interval) { +CX_TEST_SUBROUTINE(test_httpclient, cxstring *response_blocks, size_t num_blocks, CxBuffer *out, int error_interval) { pthread_mutex_init(&test_mutex, NULL); pthread_cond_init(&test_cond, NULL); @@ -80,26 +81,29 @@ http_client_set_method(client, "GET"); http_client_set_uri(client, "/testx01"); + test_finished = 0; int ret = http_client_start(client); CX_TEST_ASSERT(ret == 0); - size_t response_pos = 0; - while(response_pos < response.length) { - size_t nbytes = response.length - response_pos; - const char *str = response.ptr + response_pos; - ssize_t w = write(fds[1], str, nbytes); - CX_TEST_ASSERT(w >= 0); - response_pos += w; + for(int i=0;i<num_blocks;i++) { + size_t response_pos = 0; + cxstring response = response_blocks[i]; + while(response_pos < response.length) { + size_t nbytes = response.length - response_pos; + const char *str = response.ptr + response_pos; + ssize_t w = write(fds[1], str, nbytes); + CX_TEST_ASSERT(w >= 0); + response_pos += w; + } } + close(fds[1]); pthread_mutex_lock(&test_mutex); if(test_finished == 0) { pthread_cond_wait(&test_cond, &test_mutex); } - pthread_mutex_unlock(&test_mutex); - - + pthread_mutex_unlock(&test_mutex); } CX_TEST(test_http_client_simple_get1) { @@ -111,9 +115,76 @@ "Hello World!\n"); CxBuffer *out = cxBufferCreate(NULL, NULL, 256, CX_BUFFER_AUTO_EXTEND|CX_BUFFER_FREE_CONTENTS); - CX_TEST_CALL_SUBROUTINE(test_httpclient, response, out, 1024, 0); + CX_TEST_CALL_SUBROUTINE(test_httpclient, &response, 1, out, 0); + CX_TEST_ASSERT(!cx_strcmp(cx_strn(out->space, out->size), "Hello World!\n")); + + cxBufferFree(out); + } +} + +CX_TEST(test_http_client_simple_get_line_io) { + CX_TEST_DO { + cxstring response[8]; + response[0] = cx_str("HTTP/1.1 200 OK\r\n"); + response[1] = cx_str("Content-length: 13\r\n"); + response[2] = cx_str("\r\n"); + response[3] = cx_str("Hello World!\n"); + + CxBuffer *out = cxBufferCreate(NULL, NULL, 256, CX_BUFFER_AUTO_EXTEND|CX_BUFFER_FREE_CONTENTS); + + CX_TEST_CALL_SUBROUTINE(test_httpclient, response, 4, out, 0); CX_TEST_ASSERT(!cx_strcmp(cx_strn(out->space, out->size), "Hello World!\n")); cxBufferFree(out); } } + +CX_TEST(test_http_client_simple_get_small_blocksize) { + CX_TEST_DO { + cxstring response[16]; + response[0] = cx_str("HTTP/1.1"); + response[1] = cx_str(" 2"); + response[2] = cx_str("00 "); + response[3] = cx_str(" O"); + response[4] = cx_str("K\r\nContent-"); + response[5] = cx_str("length:"); + response[6] = cx_str(" 26"); + response[7] = cx_str("\r"); + response[8] = cx_str("\nHost"); + response[9] = cx_str(": localhost\r\n\r\nHello"); + response[10] = cx_str(" World!\n"); + response[11] = cx_str("He"); + response[12] = cx_str("llo Wor"); + response[13] = cx_str("l"); + response[14] = cx_str("d!"); + response[15] = cx_str("\n"); + + CxBuffer *out = cxBufferCreate(NULL, NULL, 256, CX_BUFFER_AUTO_EXTEND|CX_BUFFER_FREE_CONTENTS); + + CX_TEST_CALL_SUBROUTINE(test_httpclient, response, 16, out, 0); + CX_TEST_ASSERT(!cx_strcmp(cx_strn(out->space, out->size), "Hello World!\nHello World!\n")); + + cxBufferFree(out); + } +} + +CX_TEST(test_http_client_simple_get_1b_blocksize) { + CX_TEST_DO { + cxstring response_str = cx_str( + "HTTP/1.1 200 OK\r\n" + "Content-length: 13\r\n" + "\r\n" + "Hello World!\n"); + cxstring *response = calloc(response_str.length, sizeof(cxstring)); + for(int i=0;i<response_str.length;i++) { + response[i] = cx_strn(response_str.ptr+i, 1); + } + + CxBuffer *out = cxBufferCreate(NULL, NULL, 256, CX_BUFFER_AUTO_EXTEND|CX_BUFFER_FREE_CONTENTS); + + CX_TEST_CALL_SUBROUTINE(test_httpclient, response, response_str.length, out, 0); + CX_TEST_ASSERT(!cx_strcmp(cx_strn(out->space, out->size), "Hello World!\n")); + + cxBufferFree(out); + } +}
--- a/src/server/test/httpclient.h Tue Feb 24 12:28:58 2026 +0100 +++ b/src/server/test/httpclient.h Tue Feb 24 21:28:06 2026 +0100 @@ -36,6 +36,9 @@ #endif CX_TEST(test_http_client_simple_get1); +CX_TEST(test_http_client_simple_get_line_io); +CX_TEST(test_http_client_simple_get_small_blocksize); +CX_TEST(test_http_client_simple_get_1b_blocksize); #ifdef __cplusplus
--- a/src/server/test/main.c Tue Feb 24 12:28:58 2026 +0100 +++ b/src/server/test/main.c Tue Feb 24 21:28:06 2026 +0100 @@ -209,6 +209,9 @@ // http tests http_client_add_tests(suite); cx_test_register(suite, test_http_client_simple_get1); + cx_test_register(suite, test_http_client_simple_get_line_io); + cx_test_register(suite, test_http_client_simple_get_small_blocksize); + cx_test_register(suite, test_http_client_simple_get_1b_blocksize); // plugin tests #ifdef ENABLE_POSTGRESQL