src/server/test/httpclient.c

changeset 736
f707afcd4218
parent 713
929309bbf6ae
--- a/src/server/test/httpclient.c	Tue Mar 17 21:01:57 2026 +0100
+++ b/src/server/test/httpclient.c	Wed Mar 18 21:42:35 2026 +0100
@@ -43,6 +43,9 @@
 static pthread_cond_t test_cond;
 static volatile int test_finished;
 
+static size_t response_body_write_fail_after = 0;
+static int last_http_client_error = 0;
+
 void http_client_tests_init(void) {
     pthread_mutex_init(&test_mutex, NULL);
     pthread_cond_init(&test_cond, NULL);
@@ -62,13 +65,18 @@
     pthread_mutex_lock(&test_mutex);
     pthread_cond_signal(&test_cond);
     pthread_mutex_unlock(&test_mutex);
+    last_http_client_error = client->error;
     http_client_free(client);
     test_finished = 1;
 }
 
 static ssize_t test_response_body_write(HttpClient *client, void *buf, size_t nbytes, void *userdata) {
     char *str = buf;
-    return cxBufferWrite(str, 1, nbytes, userdata);
+    CxBuffer *buffer = userdata;
+    if(response_body_write_fail_after > 0 && buffer->pos > response_body_write_fail_after) {
+        return HTTP_CLIENT_CALLBACK_ERROR;
+    }
+    return cxBufferWrite(str, 1, nbytes, buffer);
 }
 
 static cxstring request_body_str;
@@ -133,7 +141,9 @@
             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);
+            if(response_body_write_fail_after == 0) {
+                CX_TEST_ASSERT(w >= 0);
+            }
             response_pos += w;
         }
     }
@@ -332,3 +342,23 @@
         cxBufferFree(out);
     }
 }
+
+CX_TEST(test_http_client_response_io_error) {
+    CX_TEST_DO {
+        size_t content_length = 1024*1024*16;
+        char *content = malloc(content_length);
+        memset(content, 'f', content_length);
+        
+        cxmutstr response_m = cx_strcat(CX_NULLSTR, 2, cx_str("HTTP/1.1 200 OK\r\nCOntent-length: 16777216\r\n\r\n"), cx_strn(content, content_length));
+        cxstring response = cx_strcast(response_m);
+        
+        CxBuffer *out = cxBufferCreate(NULL, NULL, content_length, CX_BUFFER_AUTO_EXTEND|CX_BUFFER_FREE_CONTENTS);
+        
+        response_body_write_fail_after = 2048;
+        CX_TEST_CALL_SUBROUTINE(test_httpclient, cx_str(NULL), FALSE, &response, 1, out);
+        CX_TEST_ASSERT(last_http_client_error == 1);
+        cxBufferFree(out);
+        free(content);
+    }
+    response_body_write_fail_after = 0;
+}

mercurial