summaryrefslogtreecommitdiff
path: root/sapi/cli/php_cli_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'sapi/cli/php_cli_server.c')
-rw-r--r--sapi/cli/php_cli_server.c174
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)