diff --git a/.gitignore b/.gitignore index cf11cd0ac20f9..d2f10ccdfa77b 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,10 @@ # Various temporary generated files *.tmp +# editor includes +*.iml +.idea + # ------------------------------------------------------------------------------ # Generated by the PHP build system # ------------------------------------------------------------------------------ @@ -251,6 +255,8 @@ phpt.* # Temporary PHP INI configuration file(s) for tests, generated by `make test` tmp-php.ini +php.ini +.DS_Store # ------------------------------------------------------------------------------ # Generated by GCC's gcov and LCOV via build/Makefile.gcov @@ -261,6 +267,7 @@ tmp-php.ini /gcovr_html/ /lcov_html/ /php_lcov.info +/compile_commands.json # ------------------------------------------------------------------------------ # Archives generated during the PHP release process diff --git a/NEWS b/NEWS index 198b040dc5a45..166f4e486809c 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.4.0alpha1 +- apache2handler: + . Added the apache_connection_stream() function for CGI WebSockets. (Richard Tyler Miles) + - Core: . Added zend_call_stack_get implementation for NetBSD, DragonFlyBSD, Solaris and Haiku. (David Carlier) diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c index 8926485025a3b..4acd2f1104736 100644 --- a/ext/standard/php_fopen_wrapper.c +++ b/ext/standard/php_fopen_wrapper.c @@ -215,23 +215,20 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *pa } if (!strcasecmp(path, "input")) { - php_stream_input_t *input; - + php_stream_input_t *input; if ((options & STREAM_OPEN_FOR_INCLUDE) && !PG(allow_url_include) ) { if (options & REPORT_ERRORS) { php_error_docref(NULL, E_WARNING, "URL file-access is disabled in the server configuration"); } return NULL; } - input = ecalloc(1, sizeof(*input)); if ((input->body = SG(request_info).request_body)) { php_stream_rewind(input->body); - } else { + } else { input->body = php_stream_temp_create_ex(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE, PG(upload_tmp_dir)); SG(request_info).request_body = input->body; - } - + } return php_stream_alloc(&php_stream_input_ops, input, 0, "rb"); } @@ -261,7 +258,7 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *pa if (!strcmp(sapi_module.name, "cli")) { static int cli_out = 0; fd = STDOUT_FILENO; - if (cli_out++) { + if (cli_out) { fd = dup(fd); } else { cli_out = 1; @@ -277,7 +274,7 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *pa if (!strcmp(sapi_module.name, "cli")) { static int cli_err = 0; fd = STDERR_FILENO; - if (cli_err++) { + if (cli_err) { fd = dup(fd); } else { cli_err = 1; diff --git a/sapi/apache2handler/php_functions.c b/sapi/apache2handler/php_functions.c index 27b8aab1dfb50..4420fc2c3f681 100644 --- a/sapi/apache2handler/php_functions.c +++ b/sapi/apache2handler/php_functions.c @@ -50,6 +50,7 @@ #include "php_apache.h" #include "php_functions_arginfo.h" +#include "ext/standard/php_standard.h" #ifdef ZTS int php_apache2_info_id; @@ -216,6 +217,60 @@ PHP_FUNCTION(apache_response_headers) } /* }}} */ +/* {{{ The allows for direct select calls on Apache's connection socket */ +PHP_FUNCTION(apache_connection_stream) { + php_struct *ctx = SG(server_context); + request_rec *r; + apr_socket_t *apr_sock; + int fd; + php_stream *stream; + + + // Check for proper parsing of parameters (none expected) + ZEND_PARSE_PARAMETERS_NONE(); + + // Ensure the server context is available + if (!ctx) { + php_error_docref(NULL, E_WARNING, "Server context is not available"); + RETURN_FALSE; + } + + r = ctx->r; + + // Ensure the request record is available + if (!r) { + php_error_docref(NULL, E_WARNING, "Request record is not available"); + RETURN_FALSE; + } + + apr_sock = ap_get_conn_socket(r->connection); + + // Ensure the connection socket is available + if (!apr_sock) { + php_error_docref(NULL, E_WARNING, "Failed to obtain connection socket"); + RETURN_FALSE; + } + + // Get the native descriptor + if (apr_os_sock_get(&fd, apr_sock) != APR_SUCCESS) { + php_error_docref(NULL, E_WARNING, "Failed to get native socket descriptor"); + RETURN_FALSE; + } + + // Use php_stream_sock_open_from_socket() to create a PHP stream + stream = php_stream_sock_open_from_socket(fd, NULL); + + // Check if the stream was successfully created + if (!stream) { + php_error_docref(NULL, E_WARNING, "Failed to open stream from socket"); + RETURN_FALSE; + } + + // Convert the php_stream to a zval and return it + php_stream_to_zval(stream, return_value); +} +/* }}} */ + /* {{{ Get and set Apache request notes */ PHP_FUNCTION(apache_note) { diff --git a/sapi/apache2handler/php_functions_arginfo.h b/sapi/apache2handler/php_functions_arginfo.h index c5657e9429cab..ce6d524336759 100644 --- a/sapi/apache2handler/php_functions_arginfo.h +++ b/sapi/apache2handler/php_functions_arginfo.h @@ -41,6 +41,7 @@ ZEND_FUNCTION(apache_lookup_uri); ZEND_FUNCTION(virtual); ZEND_FUNCTION(apache_request_headers); ZEND_FUNCTION(apache_response_headers); +ZEND_FUNCTION(apache_connection_stream); ZEND_FUNCTION(apache_note); ZEND_FUNCTION(apache_setenv); ZEND_FUNCTION(apache_getenv); @@ -53,6 +54,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(apache_request_headers, arginfo_apache_request_headers) ZEND_RAW_FENTRY("getallheaders", zif_apache_request_headers, arginfo_getallheaders, 0, NULL, NULL) ZEND_FE(apache_response_headers, arginfo_apache_response_headers) + ZEND_FE(apache_connection_stream, NULL) ZEND_FE(apache_note, arginfo_apache_note) ZEND_FE(apache_setenv, arginfo_apache_setenv) ZEND_FE(apache_getenv, arginfo_apache_getenv) diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c index e84defb3da469..dfcfcb6801b8b 100644 --- a/sapi/cli/php_cli_server.c +++ b/sapi/cli/php_cli_server.c @@ -458,6 +458,27 @@ PHP_FUNCTION(apache_response_headers) /* {{{ */ } /* }}} */ +PHP_FUNCTION(apache_connection_stream) /* {{{ */ +{ + php_cli_server_client *client = SG(server_context); + + // Check for proper parsing of parameters (none expected) + ZEND_PARSE_PARAMETERS_NONE(); + + // Use php_stream_sock_open_from_socket() to create a PHP stream + php_stream *stream = php_stream_sock_open_from_socket(client->sock, NULL); + + // Check if the stream was successfully created + if (!stream) { + php_error_docref(NULL, E_WARNING, "Failed to open stream from socket in cli server"); + RETURN_FALSE; + } + + // Convert the php_stream to a zval and return it + php_stream_to_zval(stream, return_value); +} +/* }}} */ + /* {{{ cli_server module */ static void cli_server_init_globals(zend_cli_server_globals *cg) @@ -506,6 +527,7 @@ const zend_function_entry server_additional_functions[] = { PHP_FE(cli_get_process_title, arginfo_cli_get_process_title) PHP_FE(apache_request_headers, arginfo_apache_request_headers) PHP_FE(apache_response_headers, arginfo_apache_response_headers) + PHP_FE(apache_connection_stream, NULL) PHP_FALIAS(getallheaders, apache_request_headers, arginfo_getallheaders) PHP_FE_END };