From 6519b0c1bb80430968e49d9808208d14e8deb0e8 Mon Sep 17 00:00:00 2001 From: Francesco Cozzuto Date: Wed, 3 Dec 2025 18:01:39 +0100 Subject: [PATCH] Fix incorrect call to http_response_builder_body_cap in toastyfs_web --- web/3p/chttp.c | 26 ++++++++++++++++++++++++++ web/3p/chttp.h | 6 ++++++ web/src/proxy_get.c | 14 +++++++++----- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/web/3p/chttp.c b/web/3p/chttp.c index 9d76058..7c5465c 100644 --- a/web/3p/chttp.c +++ b/web/3p/chttp.c @@ -2676,6 +2676,9 @@ void socket_manager_register_events( continue; j++; + if (s->silent) + continue; + // If at least one socket can be processed, return an // empty list. if (s->state == SOCKET_STATE_DIED || s->state == SOCKET_STATE_ESTABLISHED_READY) { @@ -2754,6 +2757,7 @@ int socket_manager_translate_events( s->sock = sock; s->events = 0; s->user = NULL; + s->silent = false; #ifdef HTTPS_ENABLED // Determine whether the event came from // the encrypted listener or not. @@ -2789,7 +2793,10 @@ int socket_manager_translate_events( #endif } else { + Socket *s = reg.ptrs[i]; + assert(!s->silent); + socket_update(s); } } @@ -2800,6 +2807,9 @@ int socket_manager_translate_events( continue; j++; + if (s->silent) + continue; + if (s->state == SOCKET_STATE_DIED) { events[num_events++] = (SocketEvent) { @@ -2989,6 +2999,7 @@ int socket_connect(SocketManager *sm, int num_targets, UPDATE_STATE(s->state, SOCKET_STATE_PENDING); s->sock = NATIVE_SOCKET_INVALID; s->user = user; + s->silent = false; #ifdef HTTPS_ENABLED s->server_secure_context = NULL; s->client_secure_context = NULL; @@ -3173,6 +3184,15 @@ bool socket_ready(SocketManager *sm, SocketHandle handle) return false; } +void socket_silent(SocketManager *sm, SocketHandle handle, bool value) +{ + Socket *s = handle_to_socket(sm, handle); + if (s == NULL) + return; + + s->silent = value; +} + //////////////////////////////////////////////////////////////////////////////////////// // src/byte_queue.c //////////////////////////////////////////////////////////////////////////////////////// @@ -4592,6 +4612,9 @@ check_request_buffer(HTTP_Server *server, HTTP_ServerConn *conn) // Ready assert(ret > 0); + // Stop receiving I/O events while we are building the response + socket_silent(&server->sockets, conn->handle, true); + conn->state = HTTP_SERVER_CONN_WAIT_STATUS; conn->request_len = ret; conn->response_offset = byte_queue_offset(&conn->output); @@ -5022,6 +5045,9 @@ void http_response_builder_send(HTTP_ResponseBuilder builder) conn->state = HTTP_SERVER_CONN_FLUSHING; conn->gen++; + // Enable back I/O events + socket_silent(&builder.server->sockets, conn->handle, false); + http_server_conn_process_events(builder.server, conn); } diff --git a/web/3p/chttp.h b/web/3p/chttp.h index 3c0b911..2a82e2f 100644 --- a/web/3p/chttp.h +++ b/web/3p/chttp.h @@ -481,6 +481,9 @@ typedef struct { // Native socket events that need to be monitored int events; + // If this is set, the raw socket handle shouldn't be monitored + bool silent; + // Generation counter to invalidate any SocketHandle // referring to this socket when it is freed. // Note that this counter may wrap but always skips @@ -668,6 +671,9 @@ void socket_set_user(SocketManager *sm, SocketHandle handle, void *user); // writing. bool socket_ready(SocketManager *sm, SocketHandle handle); +// When a socket is marked as silent it will not generate events +void socket_silent(SocketManager *sm, SocketHandle handle, bool value); + //////////////////////////////////////////////////////////////////////////////////////// // src/byte_queue.h //////////////////////////////////////////////////////////////////////////////////////// diff --git a/web/src/proxy_get.c b/web/src/proxy_get.c index d18b7bb..aa67146 100644 --- a/web/src/proxy_get.c +++ b/web/src/proxy_get.c @@ -12,11 +12,6 @@ bool process_request_get(ProxyState *state, ProxyOperation *operation, || request->method == HTTP_METHOD_HEAD); http_response_builder_status(builder, 200); // OK - http_response_builder_body_cap(builder, 1<<10); // TODO: pick the prealloc better - - int cap; - char *dst = http_response_builder_body_buf(builder, &cap); - // TODO: check for NULL dst ToastyString path = { request->url.path.ptr, @@ -28,10 +23,19 @@ bool process_request_get(ProxyState *state, ProxyOperation *operation, handle = toasty_begin_list(state->backend, path, TOASTY_VERSION_TAG_EMPTY); } else { + + http_response_builder_body_cap(builder, 1<<10); // TODO: pick the prealloc better + + int cap; + char *dst = http_response_builder_body_buf(builder, &cap); + // TODO: check for NULL dst + handle = toasty_begin_read(state->backend, path, 0, dst, cap, TOASTY_VERSION_TAG_EMPTY); } if (handle == TOASTY_INVALID) { + if (!path_refers_to_dir(path)) + http_response_builder_body_ack(builder, 0); http_response_builder_status(builder, 500); // Internal Server Error http_response_builder_send(builder); return false;