com php-src: Fix bug 60471 by correctly identifying unused speculative preconnections: sapi/cli/php_cli_server.c sapi/cli/php _http_parser.c sapi/cli/php_http_parser.h
[email protected] (Sara Golemon)
| Newsgroups | php.cvs |
|---|---|
| Message-ID | <[email protected]> |
Commit: fd0e71d001b76c0ce16bd2d2f7d80956ae9fc6f9 Author: Sammy Kaye Powers <[email protected]> Wed, 29 Mar 2017 09:27:18 -0500 Committer: Sara Golemon <[email protected]> Tue, 11 Apr 2017 15:08:05 -0700 Parents: 8121cb50465268d645a61f79a8bec4d144700b34 Branches: master Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=fd0e71d001b76c0ce16bd2d2f7d80956ae9fc6f9 Log: Fix bug 60471 by correctly identifying unused speculative preconnections * Correctly identify unused speculative preconnections from browsers like Chrome and Firefox * Add a new message to the debug level that is emitted when a TCP connection is closed without sending any request (a preconnection) * Fix an issue where the existing debug messages were not being displayed even when debug mode was enabled Bugs: https://bugs.php.net/60471 Changed paths: M sapi/cli/php_cli_server.c M sapi/cli/php_http_parser.c M sapi/cli/php_http_parser.h Diff: diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c index de4cfb2..1f4eb38 100644 --- a/sapi/cli/php_cli_server.c +++ b/sapi/cli/php_cli_server.c @@ -211,6 +211,8 @@ static php_cli_server_http_response_status_code_pair template_map[] = { static int php_cli_output_is_tty = OUTPUT_NOT_CHECKED; #endif +static const char php_cli_server_request_error_unexpected_eof[] = "Unexpected EOF"; + static size_t php_cli_server_client_send_through(php_cli_server_client *client, const char *str, size_t str_len); static php_cli_server_chunk *php_cli_server_chunk_heap_new_self_contained(size_t len); static void php_cli_server_buffer_append(php_cli_server_buffer *buffer, php_cli_server_chunk *chunk); @@ -1462,7 +1464,7 @@ static void normalize_vpath(char **retval, size_t *retval_len, const char *vpath #ifdef PHP_WIN32 { char *p = decoded_vpath; - + do { if (*p == '\\') { *p = '/'; @@ -1677,7 +1679,7 @@ static int php_cli_server_client_read_request(php_cli_server_client *client, cha *errstr = php_socket_strerror(err, NULL, 0); return -1; } else if (nbytes_read == 0) { - *errstr = estrdup("Unexpected EOF"); + *errstr = estrdup(php_cli_server_request_error_unexpected_eof); return -1; } client->parser.data = client; @@ -1806,7 +1808,7 @@ static void php_cli_server_client_dtor(php_cli_server_client *client) /* {{{ */ static void php_cli_server_close_connection(php_cli_server *server, php_cli_server_client *client) /* {{{ */ { -#ifdef DEBUG +#if PHP_DEBUG php_cli_server_logf("%s Closing", client->addr_str); #endif zend_hash_index_del(&server->clients, client->sock); @@ -2297,7 +2299,13 @@ static int php_cli_server_recv_event_read_request(php_cli_server *server, php_cl char *errstr = NULL; int status = php_cli_server_client_read_request(client, &errstr); if (status < 0) { - php_cli_server_logf("%s Invalid request (%s)", client->addr_str, errstr); + if (strcmp(errstr, php_cli_server_request_error_unexpected_eof) == 0 && client->parser.state == s_start_req) { +#if PHP_DEBUG + php_cli_server_logf("%s Closed without sending a request; it was probably just an unused speculative preconnection", client->addr_str); +#endif + } else { + php_cli_server_logf("%s Invalid request (%s)", client->addr_str, errstr); + } efree(errstr); php_cli_server_close_connection(server, client); return FAILURE; @@ -2379,7 +2387,7 @@ static int php_cli_server_do_event_for_each_fd_callback(void *_params, php_socke closesocket(client_sock); return SUCCESS; } -#ifdef DEBUG +#if PHP_DEBUG php_cli_server_logf("%s Accepted", client->addr_str); #endif zend_hash_index_update_ptr(&server->clients, client_sock, client); diff --git a/sapi/cli/php_http_parser.c b/sapi/cli/php_http_parser.c index 59361d0..63769c1 100644 --- a/sapi/cli/php_http_parser.c +++ b/sapi/cli/php_http_parser.c @@ -195,75 +195,6 @@ static const uint8_t normal_url_char[256] = { 1, 1, 1, 1, 1, 1, 1, 0 }; -enum state - { s_dead = 1 /* important that this is > 0 */ - - , s_start_req_or_res - , s_res_or_resp_H - , s_start_res - , s_res_H - , s_res_HT - , s_res_HTT - , s_res_HTTP - , s_res_first_http_major - , s_res_http_major - , s_res_first_http_minor - , s_res_http_minor - , s_res_first_status_code - , s_res_status_code - , s_res_status - , s_res_line_almost_done - - , s_start_req - - , s_req_method - , s_req_spaces_before_url - , s_req_schema - , s_req_schema_slash - , s_req_schema_slash_slash - , s_req_host - , s_req_port - , s_req_path - , s_req_query_string_start - , s_req_query_string - , s_req_fragment_start - , s_req_fragment - , s_req_http_start - , s_req_http_H - , s_req_http_HT - , s_req_http_HTT - , s_req_http_HTTP - , s_req_first_http_major - , s_req_http_major - , s_req_first_http_minor - , s_req_http_minor - , s_req_line_almost_done - - , s_header_field_start - , s_header_field - , s_header_value_start - , s_header_value - - , s_header_almost_done - - , s_headers_almost_done - /* Important: 's_headers_almost_done' must be the last 'header' state. All - * states beyond this must be 'body' states. It is used for overflow - * checking. See the PARSING_HEADER() macro. - */ - , s_chunk_size_start - , s_chunk_size - , s_chunk_size_almost_done - , s_chunk_parameters - , s_chunk_data - , s_chunk_data_almost_done - , s_chunk_data_done - - , s_body_identity - , s_body_identity_eof - }; - - #define PARSING_HEADER(state) (state <= s_headers_almost_done && 0 == (parser->flags & F_TRAILING)) diff --git a/sapi/cli/php_http_parser.h b/sapi/cli/php_http_parser.h index fa4873a..d2fa69b 100644 --- a/sapi/cli/php_http_parser.h +++ b/sapi/cli/php_http_parser.h @@ -110,6 +110,73 @@ enum php_http_method enum php_http_parser_type { PHP_HTTP_REQUEST, PHP_HTTP_RESPONSE, PHP_HTTP_BOTH }; +enum state + { s_dead = 1 /* important that this is > 0 */ + + , s_start_req_or_res + , s_res_or_resp_H + , s_start_res + , s_res_H + , s_res_HT + , s_res_HTT + , s_res_HTTP + , s_res_first_http_major + , s_res_http_major + , s_res_first_http_minor + , s_res_http_minor + , s_res_first_status_code + , s_res_status_code + , s_res_status + , s_res_line_almost_done + + , s_start_req + + , s_req_method + , s_req_spaces_before_url + , s_req_schema + , s_req_schema_slash + , s_req_schema_slash_slash + , s_req_host + , s_req_port + , s_req_path + , s_req_query_string_start + , s_req_query_string + , s_req_fragment_start + , s_req_fragment + , s_req_http_start + , s_req_http_H + , s_req_http_HT + , s_req_http_HTT + , s_req_http_HTTP + , s_req_first_http_major + , s_req_http_major + , s_req_first_http_minor + , s_req_http_minor + , s_req_line_almost_done + + , s_header_field_start + , s_header_field + , s_header_value_start + , s_header_value + + , s_header_almost_done + + , s_headers_almost_done + /* Important: 's_headers_almost_done' must be the last 'header' state. All + * states beyond this must be 'body' states. It is used for overflow + * checking. See the PARSING_HEADER() macro. + */ + , s_chunk_size_start + , s_chunk_size + , s_chunk_size_almost_done + , s_chunk_parameters + , s_chunk_data + , s_chunk_data_almost_done + , s_chunk_data_done + + , s_body_identity + , s_body_identity_eof + }; struct php_http_parser { /** PRIVATE **/