From c072bd610c9d321016026e9ef70f689998fd2759 Mon Sep 17 00:00:00 2001 From: Edmond <1571649+edmonddantes@users.noreply.github.com> Date: Thu, 9 Jul 2026 11:15:39 +0000 Subject: [PATCH] refactor: fold single-function modules into their callers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fs_slurp_fd + http_conditional_check → send_file.c (both were shared only between send_file.c and static/http_static.c, which already include send_file.h). http_server_exceptions_register + its class-entry globals → http_server.c. Removes 3 .c + 2 .h and 3 translation units; no behaviour change. 28/28 sendfile+static phpt pass. --- config.m4 | 3 -- config.w32 | 3 -- include/fs_util.h | 23 ------------ include/http_conditional.h | 28 -------------- include/send_file.h | 14 +++++++ src/fs_util.c | 64 ------------------------------- src/http_conditional.c | 40 -------------------- src/http_server.c | 28 ++++++++++++++ src/http_server_exceptions.c | 50 ------------------------ src/send_file.c | 73 ++++++++++++++++++++++++++++++++++-- src/static/http_static.c | 2 - 11 files changed, 112 insertions(+), 216 deletions(-) delete mode 100644 include/fs_util.h delete mode 100644 include/http_conditional.h delete mode 100644 src/fs_util.c delete mode 100644 src/http_conditional.c delete mode 100644 src/http_server_exceptions.c diff --git a/config.m4 b/config.m4 index 09ac6741..11f27a25 100644 --- a/config.m4 +++ b/config.m4 @@ -507,7 +507,6 @@ if test "$PHP_HTTP_SERVER" != "no"; then deps/llhttp/api.c deps/llhttp/http.c src/http_server.c - src/http_server_exceptions.c src/http_server_config.c src/http_server_class.c src/core/http_connection.c @@ -538,9 +537,7 @@ if test "$PHP_HTTP_SERVER" != "no"; then src/http_mime.c src/http_date.c src/http_etag.c - src/http_conditional.c src/http_range.c - src/fs_util.c src/http_rfc5987.c src/http_precompressed.c src/http_param_parse.c diff --git a/config.w32 b/config.w32 index e5b65e2b..4efc6221 100644 --- a/config.w32 +++ b/config.w32 @@ -15,7 +15,6 @@ if (PHP_TRUE_ASYNC_SERVER == "yes") { // it under build-dir\src\, producing LNK1181. var http_server_sources = "src\\http_server.c " + - "src\\http_server_exceptions.c " + "src\\http_server_config.c " + "src\\http_server_class.c " + "src\\http_request.c " + @@ -29,9 +28,7 @@ if (PHP_TRUE_ASYNC_SERVER == "yes") { "src\\http_mime.c " + "src\\http_date.c " + "src\\http_etag.c " + - "src\\http_conditional.c " + "src\\http_range.c " + - "src\\fs_util.c " + "src\\http_rfc5987.c " + "src\\http_precompressed.c " + "src\\http_param_parse.c " + diff --git a/include/fs_util.h b/include/fs_util.h deleted file mode 100644 index a34836f2..00000000 --- a/include/fs_util.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) TrueAsync | - +----------------------------------------------------------------------+ - | Licensed under the Apache License, Version 2.0 | - +----------------------------------------------------------------------+ -*/ - -/* Synchronous filesystem helpers used by the small-file fallback paths. */ - -#ifndef TRUE_ASYNC_FS_UTIL_H -#define TRUE_ASYNC_FS_UTIL_H - -#include "Zend/zend_string.h" -#include -#include "win32_compat.h" - -/* Read exactly `expected_size` bytes from `fd` into a freshly-allocated - * zend_string. Retries EINTR. Returns NULL on any IO error or on - * premature EOF. */ -zend_string *fs_slurp_fd(int fd, size_t expected_size); - -#endif diff --git a/include/http_conditional.h b/include/http_conditional.h deleted file mode 100644 index c4ce2f14..00000000 --- a/include/http_conditional.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) TrueAsync | - +----------------------------------------------------------------------+ - | Licensed under the Apache License, Version 2.0 | - +----------------------------------------------------------------------+ -*/ - -/* Conditional-GET evaluation (If-None-Match / If-Modified-Since → - * 304). Single point of decision, callable from any module that - * delivers a representation. */ - -#ifndef TRUE_ASYNC_HTTP_CONDITIONAL_H -#define TRUE_ASYNC_HTTP_CONDITIONAL_H - -#include -#include -#include - -/* Returns true when the request's conditional-GET headers match the - * resource state and the server SHOULD answer 304. The etag value, - * when supplied, must be the canonical W/"..." form produced by - * http_etag_format_strong. last_modified is in seconds. */ -bool http_conditional_check(const char *if_none_match, size_t if_none_match_len, - const char *if_modified_since, size_t if_modified_since_len, - const char *etag, size_t etag_len, time_t last_modified); - -#endif diff --git a/include/send_file.h b/include/send_file.h index 87c49e24..6a0f7394 100644 --- a/include/send_file.h +++ b/include/send_file.h @@ -27,6 +27,7 @@ #include #include #include +#include #include "static/http_static_cache.h" /* http_static_cache_view_t */ @@ -148,6 +149,19 @@ send_file_result_t send_file(struct http_request_t *request, zend_object *respon const send_file_config_t *config, const send_file_cbs_t *cbs, void *user); +/* Read exactly `expected_size` bytes from `fd` into a freshly-allocated + * zend_string. Retries EINTR. Returns NULL on any IO error or on + * premature EOF. Used by the small-file slurp fast-paths. */ +zend_string *fs_slurp_fd(int fd, size_t expected_size); + +/* Returns true when the request's conditional-GET headers match the + * resource state and the server SHOULD answer 304. The etag value, + * when supplied, must be the canonical W/"..." form produced by + * http_etag_format_strong. last_modified is in seconds. */ +bool http_conditional_check(const char *if_none_match, size_t if_none_match_len, + const char *if_modified_since, size_t if_modified_since_len, + const char *etag, size_t etag_len, time_t last_modified); + /* File-size threshold below which the static-handler's slurp fast-path * is strictly cheaper than the async engine. See http_static_try_serve * routing and the matching slurp branch inside the send_file engine. */ diff --git a/src/fs_util.c b/src/fs_util.c deleted file mode 100644 index c7be6843..00000000 --- a/src/fs_util.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) TrueAsync | - +----------------------------------------------------------------------+ - | Licensed under the Apache License, Version 2.0 | - +----------------------------------------------------------------------+ -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "php.h" -#include "fs_util.h" - -#include -#ifdef PHP_WIN32 -# include /* _read() */ -#else -# include -#endif - -zend_string *fs_slurp_fd(const int fd, const size_t expected_size) -{ - if (expected_size == 0) { - return ZSTR_EMPTY_ALLOC(); - } - - zend_string *out = zend_string_alloc(expected_size, 0); - size_t total = 0; - - while (total < expected_size) { -#ifdef PHP_WIN32 - const ssize_t n = _read(fd, ZSTR_VAL(out) + total, - (unsigned int)(expected_size - total)); -#else - const ssize_t n = read(fd, ZSTR_VAL(out) + total, expected_size - total); -#endif - - if (EXPECTED(n > 0)) { - total += (size_t)n; - continue; - } - - if (n == 0) { - break; /* premature EOF */ - } - - if (errno == EINTR) { - continue; - } - - zend_string_release(out); - return NULL; - } - - if (UNEXPECTED(total != expected_size)) { - zend_string_release(out); - return NULL; - } - - ZSTR_VAL(out)[expected_size] = '\0'; - return out; -} diff --git a/src/http_conditional.c b/src/http_conditional.c deleted file mode 100644 index 4ee339c3..00000000 --- a/src/http_conditional.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) TrueAsync | - +----------------------------------------------------------------------+ - | Licensed under the Apache License, Version 2.0 | - +----------------------------------------------------------------------+ -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "php.h" -#include "http_conditional.h" -#include "http_etag.h" -#include "http_date.h" - -bool http_conditional_check(const char *if_none_match, size_t if_none_match_len, - const char *if_modified_since, size_t if_modified_since_len, - const char *etag, size_t etag_len, time_t last_modified) -{ - /* RFC 9110 §13.1.2: If-None-Match takes precedence; If-Modified- - * Since is consulted only when If-None-Match is absent. */ - if (if_none_match_len > 0 && if_none_match != NULL) { - return http_etag_match_inm(if_none_match, if_none_match_len, etag, etag_len); - } - - if (if_modified_since_len > 0 && if_modified_since != NULL) { - const time_t since = http_date_parse_imf(if_modified_since, if_modified_since_len); - - if (since == (time_t)-1) { - return false; - } - - /* "Not modified" iff last_modified <= since. */ - return last_modified <= since; - } - - return false; -} diff --git a/src/http_server.c b/src/http_server.c index 7e714bcc..45d8c09e 100644 --- a/src/http_server.c +++ b/src/http_server.c @@ -12,6 +12,7 @@ #include "php.h" #include "php_ini.h" +#include "zend_exceptions.h" #include "ext/standard/info.h" #include "zend_smart_str.h" #include "php_http_server.h" @@ -43,10 +44,37 @@ /* Include generated arginfo */ #include "../stubs/functions.php_arginfo.h" +#include "../stubs/HttpServerExceptions.php_arginfo.h" /* Declare module globals */ ZEND_DECLARE_MODULE_GLOBALS(http_server) +/* Exception class entries */ +zend_class_entry *http_server_exception_ce; +zend_class_entry *http_server_runtime_exception_ce; +zend_class_entry *http_server_invalid_argument_exception_ce; +zend_class_entry *http_server_connection_exception_ce; +zend_class_entry *http_server_protocol_exception_ce; +zend_class_entry *http_server_timeout_exception_ce; +zend_class_entry *http_exception_ce; + +void http_server_exceptions_register(void) +{ + http_server_exception_ce = register_class_TrueAsync_HttpServerException(); + + http_server_runtime_exception_ce = register_class_TrueAsync_HttpServerRuntimeException(http_server_exception_ce); + http_server_invalid_argument_exception_ce = register_class_TrueAsync_HttpServerInvalidArgumentException(http_server_exception_ce); + http_server_connection_exception_ce = register_class_TrueAsync_HttpServerConnectionException(http_server_exception_ce); + http_server_protocol_exception_ce = register_class_TrueAsync_HttpServerProtocolException(http_server_exception_ce); + http_server_timeout_exception_ce = register_class_TrueAsync_HttpServerTimeoutException(http_server_exception_ce); + + /* HttpException — separate hierarchy. Extends Async\AsyncCancellation + * (resolved at registration time inside the arginfo helper). User + * handlers throw it to set a precise HTTP error response; we also + * use it internally for cancelling in-flight handlers on parser errors. */ + http_exception_ce = register_class_TrueAsync_HttpException(); +} + extern zval* http_request_create_from_parsed(http_request_t *req); /* PHP Functions */ diff --git a/src/http_server_exceptions.c b/src/http_server_exceptions.c deleted file mode 100644 index ffacb835..00000000 --- a/src/http_server_exceptions.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) TrueAsync | - +----------------------------------------------------------------------+ - | Licensed under the Apache License, Version 2.0 | - +----------------------------------------------------------------------+ -*/ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "php.h" -#include "zend_exceptions.h" -#include "Zend/zend_async_API.h" -#include "php_http_server.h" - -/* Include generated arginfo */ -#include "../stubs/HttpServerExceptions.php_arginfo.h" - -/* Class entries */ -zend_class_entry *http_server_exception_ce; -zend_class_entry *http_server_runtime_exception_ce; -zend_class_entry *http_server_invalid_argument_exception_ce; -zend_class_entry *http_server_connection_exception_ce; -zend_class_entry *http_server_protocol_exception_ce; -zend_class_entry *http_server_timeout_exception_ce; -zend_class_entry *http_exception_ce; - -/* {{{ http_server_exceptions_register */ -void http_server_exceptions_register(void) -{ - /* Register base exception */ - http_server_exception_ce = register_class_TrueAsync_HttpServerException(); - - /* Register derived exceptions */ - http_server_runtime_exception_ce = register_class_TrueAsync_HttpServerRuntimeException(http_server_exception_ce); - http_server_invalid_argument_exception_ce = register_class_TrueAsync_HttpServerInvalidArgumentException(http_server_exception_ce); - http_server_connection_exception_ce = register_class_TrueAsync_HttpServerConnectionException(http_server_exception_ce); - http_server_protocol_exception_ce = register_class_TrueAsync_HttpServerProtocolException(http_server_exception_ce); - http_server_timeout_exception_ce = register_class_TrueAsync_HttpServerTimeoutException(http_server_exception_ce); - - /* HttpException — separate hierarchy. Extends Async\AsyncCancellation - * (resolved at registration time inside the arginfo helper). User - * handlers throw it to set a precise HTTP error response; we also - * use it internally for cancelling in-flight handlers on parser - * errors. */ - http_exception_ce = register_class_TrueAsync_HttpException(); -} -/* }}} */ diff --git a/src/send_file.c b/src/send_file.c index 03484128..84d73db4 100644 --- a/src/send_file.c +++ b/src/send_file.c @@ -27,14 +27,14 @@ #include "http_mime.h" #include "http_etag.h" #include "http_date.h" -#include "http_conditional.h" #include "http_range.h" -#include "fs_util.h" #include "static/static_handler.h" /* http_static_cache_acquire decl */ #include "static/http_static_cache.h" #include -#ifndef PHP_WIN32 +#ifdef PHP_WIN32 +# include /* _read() */ +#else # include # include #endif @@ -771,3 +771,70 @@ send_file_result_t send_file(struct http_request_t *request, zend_object *respon return SEND_FILE_ASYNC; } + +zend_string *fs_slurp_fd(const int fd, const size_t expected_size) +{ + if (expected_size == 0) { + return ZSTR_EMPTY_ALLOC(); + } + + zend_string *out = zend_string_alloc(expected_size, 0); + size_t total = 0; + + while (total < expected_size) { +#ifdef PHP_WIN32 + const ssize_t n = _read(fd, ZSTR_VAL(out) + total, + (unsigned int)(expected_size - total)); +#else + const ssize_t n = read(fd, ZSTR_VAL(out) + total, expected_size - total); +#endif + + if (EXPECTED(n > 0)) { + total += (size_t)n; + continue; + } + + if (n == 0) { + break; /* premature EOF */ + } + + if (errno == EINTR) { + continue; + } + + zend_string_release(out); + return NULL; + } + + if (UNEXPECTED(total != expected_size)) { + zend_string_release(out); + return NULL; + } + + ZSTR_VAL(out)[expected_size] = '\0'; + return out; +} + +bool http_conditional_check(const char *if_none_match, size_t if_none_match_len, + const char *if_modified_since, size_t if_modified_since_len, + const char *etag, size_t etag_len, time_t last_modified) +{ + /* RFC 9110 §13.1.2: If-None-Match takes precedence; If-Modified- + * Since is consulted only when If-None-Match is absent. */ + if (if_none_match_len > 0 && if_none_match != NULL) { + return http_etag_match_inm(if_none_match, if_none_match_len, etag, etag_len); + } + + if (if_modified_since_len > 0 && if_modified_since != NULL) { + const time_t since = http_date_parse_imf(if_modified_since, if_modified_since_len); + + if (since == (time_t)-1) { + return false; + } + + /* "Not modified" iff last_modified <= since. */ + return last_modified <= since; + } + + return false; +} diff --git a/src/static/http_static.c b/src/static/http_static.c index e90c21e7..ed410491 100644 --- a/src/static/http_static.c +++ b/src/static/http_static.c @@ -37,9 +37,7 @@ #include "static/http_static_path.h" #include "http_etag.h" #include "http_date.h" -#include "http_conditional.h" #include "http_range.h" -#include "fs_util.h" #include "http_precompressed.h" #include "send_file.h" #include "static/http_static_cache.h"