diff options
Diffstat (limited to 'sapi/cli/php_cli_server.c')
| -rw-r--r-- | sapi/cli/php_cli_server.c | 100 | 
1 files changed, 71 insertions, 29 deletions
| diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c index f76199af9a..0853db99bb 100644 --- a/sapi/cli/php_cli_server.c +++ b/sapi/cli/php_cli_server.c @@ -2,7 +2,7 @@     +----------------------------------------------------------------------+     | PHP Version 7                                                        |     +----------------------------------------------------------------------+ -   | Copyright (c) 1997-2015 The PHP Group                                | +   | Copyright (c) 1997-2016 The PHP Group                                |     +----------------------------------------------------------------------+     | This source file is subject to version 3.01 of the PHP license,      |     | that is bundled with this package in the file LICENSE, and is        | @@ -94,8 +94,9 @@  #include "ext/standard/file.h" /* for php_set_sock_blocking() :-( */  #include "zend_smart_str.h"  #include "ext/standard/html.h" -#include "ext/standard/url.h" /* for php_url_decode() */ +#include "ext/standard/url.h" /* for php_raw_url_decode() */  #include "ext/standard/php_string.h" /* for php_dirname() */ +#include "ext/date/php_date.h" /* for php_format_date() */  #include "php_network.h"  #include "php_http_parser.h" @@ -339,15 +340,24 @@ static void append_http_status_line(smart_str *buffer, int protocol_version, int  static void append_essential_headers(smart_str* buffer, php_cli_server_client *client, int persistent) /* {{{ */  { -	{ -		char *val; -		if (NULL != (val = zend_hash_str_find_ptr(&client->request.headers, "host", sizeof("host")-1))) { -			smart_str_appendl_ex(buffer, "Host", sizeof("Host") - 1, persistent); -			smart_str_appendl_ex(buffer, ": ", sizeof(": ") - 1, persistent); -			smart_str_appends_ex(buffer, val, persistent); -			smart_str_appendl_ex(buffer, "\r\n", 2, persistent); -		} +	char *val; +	struct timeval tv = {0}; + +	if (NULL != (val = zend_hash_str_find_ptr(&client->request.headers, "host", sizeof("host")-1))) { +		smart_str_appendl_ex(buffer, "Host", sizeof("Host") - 1, persistent); +		smart_str_appendl_ex(buffer, ": ", sizeof(": ") - 1, persistent); +		smart_str_appends_ex(buffer, val, persistent); +		smart_str_appendl_ex(buffer, "\r\n", 2, persistent);  	} + +	if (!gettimeofday(&tv, NULL)) { +		zend_string *dt = php_format_date("r", 1, tv.tv_sec, 1); +		smart_str_appendl_ex(buffer, "Date: ", 6, persistent); +		smart_str_appends_ex(buffer, dt->val, persistent); +		smart_str_appendl_ex(buffer, "\r\n", 2, persistent); +		zend_string_release(dt); +	} +  	smart_str_appendl_ex(buffer, "Connection: close\r\n", sizeof("Connection: close\r\n") - 1, persistent);  } /* }}} */ @@ -472,7 +482,7 @@ const zend_function_entry server_additional_functions[] = {  	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) -	{NULL, NULL, NULL} +	PHP_FE_END  };  static int sapi_cli_server_startup(sapi_module_struct *sapi_module) /* {{{ */ @@ -604,6 +614,9 @@ static int sapi_cli_server_register_entry_cb(char **entry, int num_args, va_list  			}  		}  		spprintf(&real_key, 0, "%s_%s", "HTTP", key); +		if (strcmp(key, "CONTENT_TYPE") == 0 || strcmp(key, "CONTENT_LENGTH") == 0) { +			sapi_cli_server_register_variable(track_vars_array, key, *entry); +		}  		sapi_cli_server_register_variable(track_vars_array, real_key, *entry);  		efree(key);  		efree(real_key); @@ -657,10 +670,7 @@ static void sapi_cli_server_register_variables(zval *track_vars_array) /* {{{ */  	if (SG(request_info).path_translated) {  		sapi_cli_server_register_variable(track_vars_array, "SCRIPT_FILENAME", SG(request_info).path_translated);  	} else if (client->server->router) { -		char *temp; -		spprintf(&temp, 0, "%s/%s", client->server->document_root, client->server->router); -		sapi_cli_server_register_variable(track_vars_array, "SCRIPT_FILENAME", temp); -		efree(temp); +		sapi_cli_server_register_variable(track_vars_array, "SCRIPT_FILENAME", client->server->router);  	}  	if (client->request.path_info) {  		sapi_cli_server_register_variable(track_vars_array, "PATH_INFO", client->request.path_info); @@ -679,7 +689,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_message(char *msg) /* {{{ */ +static void sapi_cli_server_log_message(char *msg, int syslog_type_int) /* {{{ */  {  	char buf[52]; @@ -992,7 +1002,11 @@ static int php_cli_server_content_sender_send(php_cli_server_content_sender *sen  			if (nbytes_sent < 0) {  				*nbytes_sent_total = _nbytes_sent_total;  				return php_socket_errno(); +#ifdef PHP_WIN32  			} else if (nbytes_sent == chunk->data.heap.len) { +#else +			} else if (nbytes_sent == (ssize_t)chunk->data.heap.len) { +#endif  				php_cli_server_chunk_dtor(chunk);  				pefree(chunk, 1);  				sender->buffer.first = next; @@ -1015,7 +1029,11 @@ static int php_cli_server_content_sender_send(php_cli_server_content_sender *sen  			if (nbytes_sent < 0) {  				*nbytes_sent_total = _nbytes_sent_total;  				return php_socket_errno(); +#ifdef PHP_WIN32  			} else if (nbytes_sent == chunk->data.immortal.len) { +#else +			} else if (nbytes_sent == (ssize_t)chunk->data.immortal.len) { +#endif  				php_cli_server_chunk_dtor(chunk);  				pefree(chunk, 1);  				sender->buffer.first = next; @@ -1166,7 +1184,7 @@ static void php_cli_server_logf(const char *format, ...) /* {{{ */  	}  	if (sapi_module.log_message) { -		sapi_module.log_message(buf); +		sapi_module.log_message(buf, -1);  	}  	efree(buf); @@ -1382,7 +1400,7 @@ static void php_cli_server_request_translate_vpath(php_cli_server_request *reque  	*p = '\0';  	q = p;  	while (q > buf) { -		if (!zend_stat(buf, &sb)) { +		if (!php_sys_stat(buf, &sb)) {  			if (sb.st_mode & S_IFDIR) {  				const char **file = index_files;  				if (q[-1] != DEFAULT_SLASH) { @@ -1391,7 +1409,7 @@ static void php_cli_server_request_translate_vpath(php_cli_server_request *reque  				while (*file) {  					size_t l = strlen(*file);  					memmove(q, *file, l + 1); -					if (!zend_stat(buf, &sb) && (sb.st_mode & S_IFREG)) { +					if (!php_sys_stat(buf, &sb) && (sb.st_mode & S_IFREG)) {  						q += l;  						break;  					} @@ -1464,7 +1482,19 @@ static void normalize_vpath(char **retval, size_t *retval_len, const char *vpath  		return;  	} -	decoded_vpath_end = decoded_vpath + php_url_decode(decoded_vpath, (int)vpath_len); +	decoded_vpath_end = decoded_vpath + php_raw_url_decode(decoded_vpath, (int)vpath_len); + +#ifdef PHP_WIN32 +	{ +		char *p = decoded_vpath; +		 +		do { +			if (*p == '\\') { +				*p = '/'; +			} +		} while (*p++); +	} +#endif  	p = decoded_vpath; @@ -1680,7 +1710,7 @@ static int php_cli_server_client_read_request(php_cli_server_client *client, cha  	}  	client->parser.data = client;  	nbytes_consumed = php_http_parser_execute(&client->parser, &settings, buf, nbytes_read); -	if (nbytes_consumed != nbytes_read) { +	if (nbytes_consumed != (size_t)nbytes_read) {  		if (buf[0] & 0x80 /* SSLv2 */ || buf[0] == 0x16 /* SSLv3/TLSv1 */) {  			*errstr = estrdup("Unsupported SSL request");  		} else { @@ -1832,7 +1862,7 @@ static int php_cli_server_send_error_page(php_cli_server *server, php_cli_server  		if (!chunk) {  			goto fail;  		} -		snprintf(chunk->data.heap.p, chunk->data.heap.len, prologue_template, status, status_string, ZSTR_VAL(escaped_request_uri)); +		snprintf(chunk->data.heap.p, chunk->data.heap.len, prologue_template, status, status_string);  		chunk->data.heap.len = strlen(chunk->data.heap.p);  		php_cli_server_buffer_append(&client->content_sender.buffer, chunk);  	} @@ -1940,6 +1970,19 @@ static int php_cli_server_begin_send_static(php_cli_server *server, php_cli_serv  		return php_cli_server_send_error_page(server, client, 400);  	} +#ifdef PHP_WIN32 +	/* The win32 namespace will cut off trailing dots and spaces. Since the +	   VCWD functionality isn't used here, a sophisticated functionality +	   would have to be reimplemented to know ahead there are no files +	   with invalid names there. The simplest is just to forbid invalid +	   filenames, which is done here. */ +	if (client->request.path_translated && +		('.' == client->request.path_translated[client->request.path_translated_len-1] || +		 ' ' == client->request.path_translated[client->request.path_translated_len-1])) { +		return php_cli_server_send_error_page(server, client, 500 TSRMLS_CC); +	} +#endif +  	fd = client->request.path_translated ? open(client->request.path_translated, O_RDONLY): -1;  	if (fd < 0) {  		return php_cli_server_send_error_page(server, client, 404); @@ -2035,6 +2078,8 @@ static int php_cli_server_dispatch_router(php_cli_server *server, php_cli_server  	zend_try {  		zval retval; + +		ZVAL_UNDEF(&retval);  		if (SUCCESS == zend_execute_scripts(ZEND_REQUIRE, &retval, 1, &zfd)) {  			if (Z_TYPE(retval) != IS_UNDEF) {  				decline = Z_TYPE(retval) == IS_FALSE; @@ -2122,12 +2167,8 @@ static int php_cli_server_mime_type_ctor(php_cli_server *server, const php_cli_s  	zend_hash_init(&server->extension_mime_types, 0, NULL, NULL, 1);  	for (pair = mime_type_map; pair->ext; pair++) { -		size_t ext_len = 0, mime_type_len = 0; - -		ext_len = strlen(pair->ext); -		mime_type_len = strlen(pair->mime_type); - -		zend_hash_str_add_mem(&server->extension_mime_types, pair->ext, ext_len, (void*)pair->mime_type, mime_type_len + 1); +		size_t ext_len = strlen(pair->ext); +		zend_hash_str_add_ptr(&server->extension_mime_types, pair->ext, ext_len, (void*)pair->mime_type);  	}  	return SUCCESS; @@ -2461,7 +2502,7 @@ int do_cli_server(int argc, char **argv) /* {{{ */  	if (document_root) {  		zend_stat_t sb; -		if (zend_stat(document_root, &sb)) { +		if (php_sys_stat(document_root, &sb)) {  			fprintf(stderr, "Directory %s does not exist.\n", document_root);  			return 1;  		} @@ -2508,6 +2549,7 @@ int do_cli_server(int argc, char **argv) /* {{{ */  #if defined(HAVE_SIGNAL_H) && defined(SIGINT)  	signal(SIGINT, php_cli_server_sigint_handler); +	zend_signal_init();  #endif  	php_cli_server_do_event_loop(&server);  	php_cli_server_dtor(&server); | 
