# HG changeset patch # User Olaf Wintermann # Date 1773866555 -3600 # Node ID f707afcd42186caca725678ffdb4eb6e2a365e25 # Parent 902b417ab6d237e38c65b4e711dc7e024dbb68e3 add test_http_client_response_io_error diff -r 902b417ab6d2 -r f707afcd4218 src/server/proxy/httpclient.c --- a/src/server/proxy/httpclient.c Tue Mar 17 21:01:57 2026 +0100 +++ b/src/server/proxy/httpclient.c Wed Mar 18 21:42:35 2026 +0100 @@ -804,7 +804,7 @@ while(client->transfer2_buffer_pos < client->transfer2_buffer_len) { char *buf = client->transfer2_buffer + client->transfer2_buffer_pos; size_t len = client->transfer2_buffer_len - client->transfer2_buffer_pos; - int ret = client->response_body_write(client, buf, len, client->response_body_write_userdata); + ssize_t ret = client->response_body_write(client, buf, len, client->response_body_write_userdata); log_ereport(LOG_DEBUG, "client_write_response: %d bytes; ret: %d", (int)len, ret); if(ret > 0) { client->transfer2_buffer_pos += ret; diff -r 902b417ab6d2 -r f707afcd4218 src/server/test/httpclient.c --- 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; +} diff -r 902b417ab6d2 -r f707afcd4218 src/server/test/httpclient.h --- a/src/server/test/httpclient.h Tue Mar 17 21:01:57 2026 +0100 +++ b/src/server/test/httpclient.h Wed Mar 18 21:42:35 2026 +0100 @@ -47,6 +47,7 @@ CX_TEST(test_http_client_post_chunked); CX_TEST(test_http_client_get_incorrect_ctlen); CX_TEST(test_http_client_broken_response); +CX_TEST(test_http_client_response_io_error); #ifdef __cplusplus } diff -r 902b417ab6d2 -r f707afcd4218 src/server/test/main.c --- a/src/server/test/main.c Tue Mar 17 21:01:57 2026 +0100 +++ b/src/server/test/main.c Wed Mar 18 21:42:35 2026 +0100 @@ -220,6 +220,7 @@ cx_test_register(suite, test_http_client_post_ctlen_large); cx_test_register(suite, test_http_client_get_incorrect_ctlen); cx_test_register(suite, test_http_client_broken_response); + cx_test_register(suite, test_http_client_response_io_error); // plugin tests #ifdef ENABLE_POSTGRESQL