Sun, 15 Feb 2026 13:30:29 +0100
add http_client_send_request test
--- a/src/server/proxy/httpclient.c Sun Feb 15 12:24:38 2026 +0100 +++ b/src/server/proxy/httpclient.c Sun Feb 15 13:30:29 2026 +0100 @@ -359,7 +359,69 @@ static CX_TEST(test_http_client_send_request) { CX_TEST_DO { + EventHandler dummy; + HttpClient *client = http_client_new(&dummy); + int fds[2]; + util_socketpair(fds); + util_socket_setnonblock(fds[0], 1); + util_socket_setnonblock(fds[1], 1); + client->socketfd = fds[0]; + int sock = fds[1]; + + // create a large test buffer, that is bigger than the socket buffer + // 32mb should be enough + size_t len = 32*1024*1024; + char *str = malloc(len); + // init the buffer with random data + for(size_t i=0;i<len;i+=sizeof(int)) { + int *p = (int*)(str+i); + *p = rand();; + } + + client->req_buffer = str; + client->req_buffer_len = len; + + // test client_send_request + + int ret = client_send_request(client); + // It is very likely that the first client_send_request call doesn't + // fully write the request buffer to the socket + // In that case it returns 1 but without the error flag + CX_TEST_ASSERT(ret == 1 && !client->error); + CX_TEST_ASSERT(client->req_buffer_pos > 0); + CX_TEST_ASSERT(client->req_buffer_pos < len); + + // read the request buffer from sock and continue with client_send_request + CxBuffer buf; + cxBufferInit(&buf, cxDefaultAllocator, NULL, len, CX_BUFFER_AUTO_EXTEND); + char tmpbuf[1024]; + int writes = 1; + while(client->req_buffer_pos < client->req_buffer_len && writes < 2000000) { + ssize_t r = read(sock, tmpbuf, 1024); + CX_TEST_ASSERT(r >= 0); + cxBufferWrite(tmpbuf, 1, r, &buf); + ret = client_send_request(client); + CX_TEST_ASSERT(ret == 0 || (ret == 1 && !client->error)); + + writes++; + } + CX_TEST_ASSERT(client->req_buffer_pos == client->req_buffer_len); + + // finish reading the request buffer from sock + ssize_t r; + while((r = read(sock, tmpbuf, 1024)) > 0 && writes < 2000000) { + cxBufferWrite(tmpbuf, 1, r, &buf); + writes++; + } + + CX_TEST_ASSERT(buf.size == len); + CX_TEST_ASSERT(!memcmp(str, buf.space, len)); + + // cleanup + close(fds[0]); + close(fds[1]); + http_client_free(client); } }
--- a/src/server/util/socket.c Sun Feb 15 12:24:38 2026 +0100 +++ b/src/server/util/socket.c Sun Feb 15 13:30:29 2026 +0100 @@ -87,6 +87,15 @@ return fd; } +int util_socketpair(int fds[2]) { + if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) { + fds[0] = -1; + fds[1] = -1; + return -1; + } + return 0; +} + int util_socket_setnonblock(int fd, int nonblock) { int flags; if ((flags = fcntl(fd, F_GETFL, 0)) == -1) {
--- a/src/server/util/socket.h Sun Feb 15 12:24:38 2026 +0100 +++ b/src/server/util/socket.h Sun Feb 15 13:30:29 2026 +0100 @@ -45,6 +45,10 @@ // returns the socket fd int util_socket_connect_local(short port); +// creates a connected socket pair (domain AF_UNIX, type SOCK_STREAM) +// returns 0 on success, -1 on error +int util_socketpair(int fds[2]); + // enables/disables non-blocking mode the for specified socket int util_socket_setnonblock(int fd, int nonblock);