diff options
Diffstat (limited to 'sapi/cli/php_cli_server.c')
-rw-r--r-- | sapi/cli/php_cli_server.c | 174 |
1 files changed, 100 insertions, 74 deletions
diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c index befa4c65f5..a32b51e3d3 100644 --- a/sapi/cli/php_cli_server.c +++ b/sapi/cli/php_cli_server.c @@ -1,7 +1,5 @@ /* +----------------------------------------------------------------------+ - | PHP Version 7 | - +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | @@ -93,9 +91,11 @@ #include "php_http_parser.h" #include "php_cli_server.h" +#include "php_cli_server_arginfo.h" #include "mime_type_map.h" #include "php_cli_process_title.h" +#include "php_cli_process_title_arginfo.h" #define OUTPUT_NOT_CHECKED -1 #define OUTPUT_IS_TTY 1 @@ -215,7 +215,7 @@ static php_cli_server_http_response_status_code_pair template_map[] = { static int php_cli_server_log_level = 3; -#if HAVE_UNISTD_H +#if HAVE_UNISTD_H || defined(PHP_WIN32) static int php_cli_output_is_tty = OUTPUT_NOT_CHECKED; #endif @@ -227,7 +227,7 @@ static void php_cli_server_buffer_append(php_cli_server_buffer *buffer, php_cli_ static void php_cli_server_logf(int type, const char *format, ...); static void php_cli_server_log_response(php_cli_server_client *client, int status, const char *message); -ZEND_DECLARE_MODULE_GLOBALS(cli_server); +ZEND_DECLARE_MODULE_GLOBALS(cli_server) /* {{{ static char php_cli_server_css[] * copied from ext/standard/info.c @@ -263,7 +263,7 @@ int php_cli_server_get_system_time(char *buf) { gettimeofday(&tv, NULL); - /* TODO: should be checked for NULL tm/return vaue */ + /* TODO: should be checked for NULL tm/return value */ php_localtime_r(&tv.tv_sec, &tm); php_asctime_r(&tm, buf); return 0; @@ -390,7 +390,7 @@ PHP_FUNCTION(apache_request_headers) /* {{{ */ zval tmp; if (zend_parse_parameters_none() == FAILURE) { - return; + RETURN_THROWS(); } client = SG(server_context); @@ -436,7 +436,7 @@ static void add_response_header(sapi_header_struct *h, zval *return_value) /* {{ PHP_FUNCTION(apache_response_headers) /* {{{ */ { if (zend_parse_parameters_none() == FAILURE) { - return; + RETURN_THROWS(); } array_init(return_value); @@ -444,8 +444,7 @@ PHP_FUNCTION(apache_response_headers) /* {{{ */ } /* }}} */ -/* {{{ cli_server module - */ +/* {{{ cli_server module */ static void cli_server_init_globals(zend_cli_server_globals *cg) { @@ -488,15 +487,12 @@ zend_module_entry cli_server_module_entry = { }; /* }}} */ -ZEND_BEGIN_ARG_INFO(arginfo_no_args, 0) -ZEND_END_ARG_INFO() - const zend_function_entry server_additional_functions[] = { - PHP_FE(cli_set_process_title, arginfo_cli_set_process_title) - PHP_FE(cli_get_process_title, arginfo_cli_get_process_title) - PHP_FE(apache_request_headers, arginfo_no_args) - PHP_FE(apache_response_headers, arginfo_no_args) - PHP_FALIAS(getallheaders, apache_request_headers, arginfo_no_args) + PHP_FE(cli_set_process_title, arginfo_cli_set_process_title) + 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_FALIAS(getallheaders, apache_request_headers, arginfo_getallheaders) PHP_FE_END }; @@ -756,7 +752,7 @@ static void sapi_cli_server_register_variables(zval *track_vars_array) /* {{{ */ zend_hash_apply_with_arguments(&client->request.headers, (apply_func_args_t)sapi_cli_server_register_entry_cb, 1, track_vars_array); } /* }}} */ -static void sapi_cli_server_log_write(int type, char *msg) /* {{{ */ +static void sapi_cli_server_log_write(int type, const char *msg) /* {{{ */ { char buf[52]; @@ -785,13 +781,12 @@ static void sapi_cli_server_log_write(int type, char *msg) /* {{{ */ #endif } /* }}} */ -static void sapi_cli_server_log_message(char *msg, int syslog_type_int) /* {{{ */ +static void sapi_cli_server_log_message(const char *msg, int syslog_type_int) /* {{{ */ { sapi_cli_server_log_write(PHP_CLI_SERVER_LOG_MESSAGE, msg); } /* }}} */ -/* {{{ sapi_module_struct cli_server_sapi_module - */ +/* {{{ sapi_module_struct cli_server_sapi_module */ sapi_module_struct cli_server_sapi_module = { "cli-server", /* name */ "Built-in HTTP server", /* pretty name */ @@ -1165,6 +1160,14 @@ static int php_cli_is_output_tty() /* {{{ */ } return php_cli_output_is_tty; } /* }}} */ +#elif defined(PHP_WIN32) +static int php_cli_is_output_tty() /* {{{ */ +{ + if (php_cli_output_is_tty == OUTPUT_NOT_CHECKED) { + php_cli_output_is_tty = php_win32_console_fileno_is_console(STDOUT_FILENO) && php_win32_console_fileno_has_vt100(STDOUT_FILENO); + } + return php_cli_output_is_tty; +} /* }}} */ #endif static void php_cli_server_log_response(php_cli_server_client *client, int status, const char *message) /* {{{ */ @@ -1174,23 +1177,17 @@ static void php_cli_server_log_response(php_cli_server_client *client, int statu zend_bool append_error_message = 0; if (PG(last_error_message)) { - switch (PG(last_error_type)) { - case E_ERROR: - case E_CORE_ERROR: - case E_COMPILE_ERROR: - case E_USER_ERROR: - case E_PARSE: - if (status == 200) { - /* the status code isn't changed by a fatal error, so fake it */ - effective_status = 500; - } + if (PG(last_error_type) & E_FATAL_ERRORS) { + if (status == 200) { + /* the status code isn't changed by a fatal error, so fake it */ + effective_status = 500; + } - append_error_message = 1; - break; + append_error_message = 1; } } -#if HAVE_UNISTD_H +#if HAVE_UNISTD_H || defined(PHP_WIN32) if (CLI_SERVER_G(color) && php_cli_is_output_tty() == OUTPUT_IS_TTY) { if (effective_status >= 500) { /* server error: red */ @@ -1222,7 +1219,8 @@ static void php_cli_server_log_response(php_cli_server_client *client, int statu /* error */ if (append_error_message) { - spprintf(&error_buf, 0, " - %s in %s on line %d", PG(last_error_message), PG(last_error_file), PG(last_error_lineno)); + spprintf(&error_buf, 0, " - %s in %s on line %d", + ZSTR_VAL(PG(last_error_message)), PG(last_error_file), PG(last_error_lineno)); if (!error_buf) { efree(basic_buf); if (message) { @@ -1840,7 +1838,7 @@ static int php_cli_server_client_read_request(php_cli_server_client *client, cha nbytes_consumed = php_http_parser_execute(&client->parser, &settings, buf, nbytes_read); if (nbytes_consumed != (size_t)nbytes_read) { if (php_cli_server_log_level >= PHP_CLI_SERVER_LOG_ERROR) { - if (buf[0] & 0x80 /* SSLv2 */ || buf[0] == 0x16 /* SSLv3/TLSv1 */) { + if ((buf[0] & 0x80) /* SSLv2 */ || buf[0] == 0x16 /* SSLv3/TLSv1 */) { *errstr = estrdup("Unsupported SSL request"); } else { *errstr = estrdup("Malformed HTTP request"); @@ -1986,7 +1984,7 @@ static int php_cli_server_send_error_page(php_cli_server *server, php_cli_server php_cli_server_content_sender_ctor(&client->content_sender); client->content_sender_initialized = 1; - escaped_request_uri = php_escape_html_entities_ex((unsigned char *)client->request.request_uri, client->request.request_uri_len, 0, ENT_QUOTES, NULL, 0); + escaped_request_uri = php_escape_html_entities_ex((const unsigned char *) client->request.request_uri, client->request.request_uri_len, 0, ENT_QUOTES, NULL, /* double_encode */ 0, /* quiet */ 0); { static const char prologue_template[] = "<!doctype html><html><head><title>%d %s</title>"; @@ -2210,8 +2208,6 @@ static int php_cli_server_dispatch_router(php_cli_server *server, php_cli_server decline = Z_TYPE(retval) == IS_FALSE; zval_ptr_dtor(&retval); } - } else { - decline = 1; } } zend_end_try(); @@ -2357,6 +2353,65 @@ static void php_cli_server_client_dtor_wrapper(zval *zv) /* {{{ */ pefree(p, 1); } /* }}} */ +/** + * Parse the host and port portions of an address specifier in + * one of the following forms: + * - hostOrIP:port + * - [hostOrIP]:port + */ +static char *php_cli_server_parse_addr(const char *addr, int *pport) { + const char *p, *end; + long port; + + if (addr[0] == '[') { + /* Encapsulated [hostOrIP]:port */ + const char *start = addr + 1; + end = strchr(start, ']'); + if (!end) { + /* No ending ] delimiter to match [ */ + return NULL; + } + + p = end + 1; + if (*p != ':') { + /* Invalid char following address/missing port */ + return NULL; + } + + port = strtol(p + 1, (char**)&p, 10); + if (p && *p) { + /* Non-numeric in port */ + return NULL; + } + if (port < 0 || port > 65535) { + /* Invalid port */ + return NULL; + } + + /* Full [hostOrIP]:port provided */ + *pport = (int)port; + return pestrndup(start, end - start, 1); + } + + end = strchr(addr, ':'); + if (!end) { + /* Missing port */ + return NULL; + } + + port = strtol(end + 1, (char**)&p, 10); + if (p && *p) { + /* Non-numeric port */ + return NULL; + } + if (port < 0 || port > 65535) { + /* Invalid port */ + return NULL; + } + *pport = (int)port; + return pestrndup(addr, end - addr, 1); +} + static int php_cli_server_ctor(php_cli_server *server, const char *addr, const char *document_root, const char *router) /* {{{ */ { int retval = SUCCESS; @@ -2367,40 +2422,9 @@ static int php_cli_server_ctor(php_cli_server *server, const char *addr, const c int err = 0; int port = 3000; php_socket_t server_sock = SOCK_ERR; - char *p = NULL; - if (addr[0] == '[') { - host = pestrdup(addr + 1, 1); - if (!host) { - return FAILURE; - } - p = strchr(host, ']'); - if (p) { - *p++ = '\0'; - if (*p == ':') { - port = strtol(p + 1, &p, 10); - if (port <= 0 || port > 65535) { - p = NULL; - } - } else if (*p != '\0') { - p = NULL; - } - } - } else { - host = pestrdup(addr, 1); - if (!host) { - return FAILURE; - } - p = strchr(host, ':'); - if (p) { - *p++ = '\0'; - port = strtol(p, &p, 10); - if (port <= 0 || port > 65535) { - p = NULL; - } - } - } - if (!p) { + host = php_cli_server_parse_addr(addr, &port); + if (!host) { fprintf(stderr, "Invalid address: %s\n", addr); retval = FAILURE; goto out; @@ -2724,10 +2748,12 @@ int do_cli_server(int argc, char **argv) /* {{{ */ sapi_module.phpinfo_as_text = 0; { + zend_bool ipv6 = strchr(server.host, ':'); php_cli_server_logf( PHP_CLI_SERVER_LOG_PROCESS, - "PHP %s Development Server (http://%s) started", - PHP_VERSION, server_bind_address); + "PHP %s Development Server (http://%s%s%s:%d) started", + PHP_VERSION, ipv6 ? "[" : "", server.host, + ipv6 ? "]" : "", server.port); } #if defined(SIGINT) |