Tue, 17 Feb 2026 20:03:06 +0100
httpclient: move code for sending the request body to a separate function
| src/server/proxy/httpclient.c | file | annotate | diff | comparison | revisions |
--- a/src/server/proxy/httpclient.c Tue Feb 17 17:43:10 2026 +0100 +++ b/src/server/proxy/httpclient.c Tue Feb 17 20:03:06 2026 +0100 @@ -252,6 +252,57 @@ return client_io(ev, event); } +static int client_send_request_body(HttpClient *client) { + size_t rbody_readsize = client->req_buffer_alloc; + size_t rbody_buf_offset = 0; + if(client->req_content_length == -1) { + // chunked transfer encoding: + // don't fill req_buffer completely, reserve some space for + // a chunk header, that will be inserted at the beginning + rbody_readsize -= 16; + rbody_buf_offset = 16; + } + while(!client->request_body_complete) { + ssize_t r = client->request_body_read(client, client->req_buffer + rbody_buf_offset, rbody_readsize, client->request_body_read_userdata); + if(r <= 0) { + if(r == HTTP_CLIENT_CALLBACK_WOULD_BLOCK) { + return 1; + } else if(r == 0) { + // EOF + client->request_body_complete = 1; + break; + } else { + // error + client->error = 1; + return 1; + } + } + + size_t startpos = 0; + if(client->req_content_length == -1) { + char chunkheader[16]; + int chunkheaderlen = snprintf(chunkheader, 16, "%zx\r\n", (size_t)r); + startpos = 16 - chunkheaderlen; + memcpy(client->req_buffer + startpos, chunkheader, chunkheaderlen); + } + + client->req_contentlength_pos += r; + client->req_buffer_pos = startpos; + client->req_buffer_len = r; + if(client_send_request(client)) { + return 1; + } + } + + if(client->req_content_length > 0 && client->req_content_length != client->req_contentlength_pos) { + // incomplete request body + client->error = 1; + return 1; + } + + return 0; +} + static int client_io(EventHandler *ev, Event *event) { HttpClient *client = event->cookie; if(client->req_buffer_pos < client->req_buffer_len) { @@ -262,38 +313,11 @@ // do we need to send a request body? if(client->req_content_length != 0) { - while(!client->request_body_complete) { - ssize_t r = client->request_body_read(client, client->req_buffer, client->req_buffer_alloc, client->request_body_read_userdata); - if(r <= 0) { - if(r == HTTP_CLIENT_CALLBACK_WOULD_BLOCK) { - return 1; - } else if(r == 0) { - // EOF - client->request_body_complete = 1; - break; - } else { - // error - client->error = 1; - return 0; - } - } - client->req_contentlength_pos += r; - client->req_buffer_pos = 0; - client->req_buffer_len = r; - if(client_send_request(client)) { - return client->error == 0; - } - } - - if(client->req_content_length > 0 && client->req_content_length != client->req_contentlength_pos) { - // incomplete request body - client->error = 1; - return 0; + if(client_send_request_body(client)) { + return client->error == 0; } } - - // writing complete, switch to read events event->events = EVENT_POLLIN;