From 291596e30ae83464744428f2be10b43bad658090 Mon Sep 17 00:00:00 2001 From: Francesco Date: Wed, 25 Mar 2026 01:57:12 +0100 Subject: [PATCH] refactor(worker): use client's connection header --- src/core/worker.c | 33 +++++++++++++++++++++++---------- src/http/handler.c | 6 ++++++ 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/core/worker.c b/src/core/worker.c index 15e8c9a..5e01574 100644 --- a/src/core/worker.c +++ b/src/core/worker.c @@ -10,6 +10,7 @@ #include "http/handler.h" #include "http/request.h" #include "http/response.h" +#include "utils/debug.h" #include "utils/error.h" /* Create epoll instance for a worker */ @@ -43,23 +44,32 @@ static cws_return worker_handle_client_data(int epfd, int client_fd, cws_config_ string_s *data = string_new("", 4096); /* Read data from socket */ - ssize_t total_bytes = cws_socket_read(client_fd, data); + int total_bytes = cws_socket_read(client_fd, data); - if (total_bytes == 0) { - /* Partial request; wait for more data */ + /* Partial request, wait for more data */ + if (total_bytes == -2) { string_free(data); return CWS_OK; } - if (total_bytes < 0) { + /* Connection closed */ + if (total_bytes == 0) { + cws_log_info("Client (fd: %d) disconnected", client_fd); + worker_close_client(epfd, client_fd); + string_free(data); + return CWS_CLIENT_DISCONNECTED_ERROR; + } + + /* Client error */ + if (total_bytes == -1) { worker_close_client(epfd, client_fd); string_free(data); return CWS_CLIENT_DISCONNECTED_ERROR; } /* Parse HTTP request */ - cws_request_s *request = cws_http_parse(data); + cws_request_s *request = cws_request_parse(data); string_free(data); if (request == NULL) { worker_close_client(epfd, client_fd); @@ -67,7 +77,7 @@ static cws_return worker_handle_client_data(int epfd, int client_fd, cws_config_ } /* Configure handler */ - char *host = cws_http_get_host(request); + char *host = cws_request_get_header(request, "host"); cws_vhost_s *vh = get_vhost(config, host); cws_handler_config_s conf = { .domain = vh->domain, @@ -83,11 +93,14 @@ static cws_return worker_handle_client_data(int epfd, int client_fd, cws_config_ cws_response_free(response); } - /* Cleanup */ - cws_http_free(request); + /* Close connection if requested */ + /* keep-alive by default (http/1.1) */ + if (!strcmp(cws_request_get_header(request, "Connection"), "close")) { + worker_close_client(epfd, client_fd); + } - /* TODO: check Connection: keep-alive */ - worker_close_client(epfd, client_fd); + /* Cleanup */ + cws_request_free(request); return CWS_OK; } diff --git a/src/http/handler.c b/src/http/handler.c index 191c4d9..77323da 100644 --- a/src/http/handler.c +++ b/src/http/handler.c @@ -51,12 +51,18 @@ cws_response_s *cws_handler_static_file(cws_request_s *request, cws_handler_conf return cws_handler_not_found(); } + /* Allocate a response object */ + /* @TODO: do not use http 200 ok as default */ cws_response_s *response = cws_response_new(HTTP_OK); if (!response) { string_free(filepath); return cws_response_error(HTTP_INTERNAL_ERROR, "Failed to create response"); } + /* Retrieve Connection header and set it in the response */ + const char *conn = cws_request_get_header(request, "Connection"); + cws_response_set_header(response, "Connection", conn); + cws_response_set_body_file(response, path); cws_log_debug("Serving file: %s (%zu bytes)", path, response->content_length); string_free(filepath);