add test for http client responses with chunked transfer encoding default tip

Thu, 19 Feb 2026 18:34:36 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 19 Feb 2026 18:34:36 +0100
changeset 687
4bded456b4a7
parent 686
9adf57ddcd0f

add test for http client responses with chunked transfer encoding

src/server/proxy/httpclient.c file | annotate | diff | comparison | revisions
src/server/util/io.c file | annotate | diff | comparison | revisions
--- a/src/server/proxy/httpclient.c	Thu Feb 19 17:05:46 2026 +0100
+++ b/src/server/proxy/httpclient.c	Thu Feb 19 18:34:36 2026 +0100
@@ -283,11 +283,6 @@
         return client->error == 0;
     }
     
-    // request finished
-    if(client->response_finished) {
-        client->response_finished(client, client->response_finished_userdata);
-    }
-    
     return 0;
 }
 
@@ -979,7 +974,7 @@
     http_client_free(client);
 }
 
-static CX_TEST(test_http_client_io_simple) {
+static CX_TEST_SUBROUTINE(test_http_client_io_simple, size_t blocksz) {
     char *response_str = 
             "HTTP/1.1 200 OK\r\n"
             "Host: localhost\r\n"
@@ -988,20 +983,92 @@
             "Hello World!\n";
     CxBuffer *buf = cxBufferCreate(NULL, NULL, 1024, CX_BUFFER_AUTO_EXTEND|CX_BUFFER_FREE_CONTENTS);
     
-    CX_TEST_DO {
-        CX_TEST_CALL_SUBROUTINE(test_http_client_io, response_str, 200, "OK", buf, 1024);
-        CX_TEST_ASSERT(buf->size == 13);
-        CX_TEST_ASSERT(!cx_strcmp(cx_strn(buf->space, buf->size), "Hello World!\n"));
-    }
+    CX_TEST_CALL_SUBROUTINE(test_http_client_io, response_str, 200, "OK", buf, blocksz);
+    CX_TEST_ASSERT(buf->size == 13);
+    CX_TEST_ASSERT(!cx_strcmp(cx_strn(buf->space, buf->size), "Hello World!\n"));
     
     cxBufferFree(buf);
 }
 
+static CX_TEST(test_http_client_io_simple_1b) {
+    CX_TEST_DO {
+        CX_TEST_CALL_SUBROUTINE(test_http_client_io_simple, 1);
+    }
+}
+
+static CX_TEST(test_http_client_io_simple_2b) {
+    CX_TEST_DO {
+        CX_TEST_CALL_SUBROUTINE(test_http_client_io_simple, 2);
+    }
+}
+
+static CX_TEST(test_http_client_io_simple_3b) {
+    CX_TEST_DO {
+        CX_TEST_CALL_SUBROUTINE(test_http_client_io_simple, 3);
+    }
+}
+
+static CX_TEST(test_http_client_io_simple_16b) {
+    CX_TEST_DO {
+        CX_TEST_CALL_SUBROUTINE(test_http_client_io_simple, 16);
+    }
+}
+
+static CX_TEST(test_http_client_io_simple_512b) {
+    CX_TEST_DO {
+        CX_TEST_CALL_SUBROUTINE(test_http_client_io_simple, 512);
+    }
+}
+
+static CX_TEST_SUBROUTINE(test_http_client_io_chunked_transfer, size_t blocksz) {
+    char *response_str = 
+            "HTTP/1.1 200 OK\r\n"
+            "Host: localhost\r\n"
+            "Transfer-encoding: chunked\r\n"
+            "\r\n"
+            "d\r\n"        
+            "Hello World!\n"
+            "\r\n"
+            "0\r\n\r\n";
+    CxBuffer *buf = cxBufferCreate(NULL, NULL, 1024, CX_BUFFER_AUTO_EXTEND|CX_BUFFER_FREE_CONTENTS);
+    
+    CX_TEST_CALL_SUBROUTINE(test_http_client_io, response_str, 200, "OK", buf, blocksz);
+    CX_TEST_ASSERT(buf->size == 13);
+    CX_TEST_ASSERT(!cx_strcmp(cx_strn(buf->space, buf->size), "Hello World!\n"));
+    
+    cxBufferFree(buf);
+}
+
+static CX_TEST(test_http_client_io_chunked_transfer_1b) {
+    CX_TEST_DO {
+        CX_TEST_CALL_SUBROUTINE(test_http_client_io_chunked_transfer, 10);
+    }
+}
+
+/*
+static CX_TEST(test_http_client_io_chunked_transfer_8b) {
+    CX_TEST_DO {
+        CX_TEST_CALL_SUBROUTINE(test_http_client_io_chunked_transfer, 16);
+    }
+}
+
+static CX_TEST(test_http_client_io_chunked_transfer_64b) {
+    CX_TEST_DO {
+        CX_TEST_CALL_SUBROUTINE(test_http_client_io_chunked_transfer, 64);
+    }
+}
+*/
+
 void http_client_add_tests(CxTestSuite *suite) {
     cx_test_register(suite, test_http_client_send_request);
     cx_test_register(suite, test_http_client_send_request_body_chunked);
     cx_test_register(suite, test_http_client_read_response_head);
     cx_test_register(suite, test_http_client_read_response_ctlen);
     cx_test_register(suite, test_http_client_read_response_ctlen_big);
-    cx_test_register(suite, test_http_client_io_simple);
+    cx_test_register(suite, test_http_client_io_simple_1b);
+    cx_test_register(suite, test_http_client_io_simple_2b);
+    cx_test_register(suite, test_http_client_io_simple_3b);
+    cx_test_register(suite, test_http_client_io_simple_16b);
+    cx_test_register(suite, test_http_client_io_simple_512b);
+    cx_test_register(suite, test_http_client_io_chunked_transfer_1b);
 }
--- a/src/server/util/io.c	Thu Feb 19 17:05:46 2026 +0100
+++ b/src/server/util/io.c	Thu Feb 19 18:34:36 2026 +0100
@@ -746,6 +746,12 @@
             if(r == 0) {
                 break;
             }
+            if(r < 0) {
+                if(rd == 0) {
+                    rd = r;
+                }
+                break;
+            }
             int chunkbuf_len = st->chunk_buf_pos + r;
             int64_t chunklen;
             int ret = http_stream_parse_chunk_header(st->chunk_buf, chunkbuf_len, st->read_total > 0 ? FALSE : TRUE, &chunklen);

mercurial