]> granicus.if.org Git - php/commitdiff
Respond with 501 to unknown request methods
authorNiklas Lindgren <nikc@iki.fi>
Wed, 12 Sep 2012 16:34:59 +0000 (19:34 +0300)
committerStanislav Malyshev <stas@php.net>
Sun, 16 Sep 2012 06:11:12 +0000 (23:11 -0700)
Fixed typo

Moved 501 response from dispatch to event_read_request

Return return value of send_error_page

NEWS
sapi/cli/php_cli_server.c
sapi/cli/php_http_parser.c
sapi/cli/php_http_parser.h
sapi/cli/tests/bug61679.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index ed08594042e4925ac1f37d623a2e490449601de7..68f423200e94290bf16fc6ccb673426eb7b5ae94 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 2012, PHP 5.4.8
 
+- CLI server:
+  . Changed response to unknown HTTP method to 501 according to RFC.
+    (Niklas Lindgren).
+
 - Core:
   . Fixed bug #63093 (Segfault while load extension failed in zts-build).
     (Laruence)
index e80ab68f806b4be10b375da66163225ceba75ef5..4d15db44aff3b64e72a59d90f882e871fd847180 100644 (file)
@@ -116,7 +116,7 @@ typedef struct php_cli_server_poller {
 } php_cli_server_poller;
 
 typedef struct php_cli_server_request {
-       enum php_http_method request_method;    
+       enum php_http_method request_method;
        int protocol_version;
        char *request_uri;
        size_t request_uri_len;
@@ -247,7 +247,8 @@ static php_cli_server_http_reponse_status_code_pair status_map[] = {
 static php_cli_server_http_reponse_status_code_pair template_map[] = {
        { 400, "<h1 class=\"h\">%s</h1><p>Your browser sent a request that this server could not understand.</p>" },
        { 404, "<h1 class=\"h\">%s</h1><p>The requested resource %s was not found on this server.</p>" },
-       { 500, "<h1 class=\"h\">%s</h1><p>The server is temporality unavaiable.</p>" }
+       { 500, "<h1 class=\"h\">%s</h1><p>The server is temporarily unavailable.</p>" },
+       { 501, "<h1 class=\"h\">%s</h1><p>Request method not supported.</p>" }
 };
 
 static php_cli_server_ext_mime_type_pair mime_type_map[] = {
@@ -275,7 +276,7 @@ static void php_cli_server_log_response(php_cli_server_client *client, int statu
 
 ZEND_DECLARE_MODULE_GLOBALS(cli_server);
 
-/* {{{ static char php_cli_server_css[] 
+/* {{{ static char php_cli_server_css[]
  * copied from ext/standard/info.c
  */
 static const char php_cli_server_css[] = "<style type=\"text/css\">\n" \
@@ -543,7 +544,7 @@ static void sapi_cli_server_register_variable(zval *track_vars_array, const char
        }
 } /* }}} */
 
-static int sapi_cli_server_register_entry_cb(char **entry TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ { 
+static int sapi_cli_server_register_entry_cb(char **entry TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ {
        zval *track_vars_array = va_arg(args, zval *);
        if (hash_key->nKeyLength) {
                char *real_key, *key;
@@ -583,7 +584,7 @@ static void sapi_cli_server_register_variables(zval *track_vars_array TSRMLS_DC)
                } else {
                        sapi_cli_server_register_variable(track_vars_array, "REMOTE_ADDR", client->addr_str TSRMLS_CC);
                }
-       } 
+       }
        {
                char *tmp;
                spprintf(&tmp, 0, "PHP %s Development Server", PHP_VERSION);
@@ -681,7 +682,7 @@ sapi_module_struct cli_server_sapi_module = {
        sapi_cli_server_log_message,    /* Log message */
        NULL,                                                   /* Get request time */
        NULL,                                                   /* Child terminate */
-       
+
        STANDARD_SAPI_MODULE_PROPERTIES
 }; /* }}} */
 
@@ -778,7 +779,7 @@ static int php_cli_server_poller_iter_on_active(php_cli_server_poller *poller, v
                        }
                }
        }
-       
+
 #else
        php_socket_t fd = 0;
        const php_socket_t max_fd = poller->max_fd;
@@ -966,7 +967,7 @@ static int php_cli_server_content_sender_send(php_cli_server_content_sender *sen
                        } else if (nbytes_sent == chunk->data.immortal.len) {
                                php_cli_server_chunk_dtor(chunk);
                                pefree(chunk, 1);
-                               sender->buffer.first = next; 
+                               sender->buffer.first = next;
                                if (!next) {
                                        sender->buffer.last = NULL;
                                }
@@ -1345,7 +1346,7 @@ static void php_cli_server_request_translate_vpath(php_cli_server_request *reque
                                }
                        }
                        break; /* regular file */
-               } 
+               }
                if (prev_path) {
                        pefree(prev_path, 1);
                        *q = DEFAULT_SLASH;
@@ -1384,7 +1385,7 @@ static void php_cli_server_request_translate_vpath(php_cli_server_request *reque
                        if (request->vpath[i] == '\\') {
                                request->vpath[i] = '/';
                        }
-               }       
+               }
        }
 #endif
        request->sb = sb;
@@ -1452,7 +1453,7 @@ static void normalize_vpath(char **retval, size_t *retval_len, const char *vpath
                        }
                }
        }
-       
+
        *decoded_vpath_end = '\0';
        *retval = decoded_vpath;
        *retval_len = decoded_vpath_end - decoded_vpath;
@@ -1812,7 +1813,7 @@ static int php_cli_server_send_error_page(php_cli_server *server, php_cli_server
                smart_str_append_generic_ex(&buffer, php_cli_server_buffer_size(&client->content_sender.buffer), 1, size_t, _unsigned);
                smart_str_appendl_ex(&buffer, "\r\n", 2, 1);
                smart_str_appendl_ex(&buffer, "\r\n", 2, 1);
-               
+
                chunk = php_cli_server_chunk_heap_new(buffer.c, buffer.c, buffer.len);
                if (!chunk) {
                        smart_str_free_ex(&buffer, 1);
@@ -1917,7 +1918,7 @@ static int php_cli_server_begin_send_static(php_cli_server *server, php_cli_serv
 }
 /* }}} */
 
-static int php_cli_server_request_startup(php_cli_server *server, php_cli_server_client *client TSRMLS_DC) { /* {{{ */ 
+static int php_cli_server_request_startup(php_cli_server *server, php_cli_server_client *client TSRMLS_DC) { /* {{{ */
        char **auth;
        php_cli_server_client_populate_request_info(client, &SG(request_info));
        if (SUCCESS == zend_hash_find(&client->request.headers, "Authorization", sizeof("Authorization"), (void**)&auth)) {
@@ -1942,8 +1943,8 @@ static int php_cli_server_request_shutdown(php_cli_server *server, php_cli_serve
        SG(server_context) = NULL;
        SG(rfc1867_uploaded_files) = NULL;
        return SUCCESS;
-}             
-/* }}} */  
+}
+/* }}} */
 
 static int php_cli_server_dispatch_router(php_cli_server *server, php_cli_server_client *client TSRMLS_DC) /* {{{ */
 {
@@ -2002,7 +2003,7 @@ static int php_cli_server_dispatch(php_cli_server *server, php_cli_server_client
                        destroy_request_info(&SG(request_info));
                        return SUCCESS;
                }
-       } 
+       }
 
        if (server->router) {
                if (!php_cli_server_dispatch_router(server, client TSRMLS_CC)) {
@@ -2016,7 +2017,7 @@ static int php_cli_server_dispatch(php_cli_server *server, php_cli_server_client
                                || SUCCESS != php_cli_server_send_error_page(server, client, 500 TSRMLS_CC)) {
                        php_cli_server_request_shutdown(server, client TSRMLS_CC);
                        return SUCCESS;
-               } 
+               }
        } else {
                if (server->router) {
                        static int (*send_header_func)(sapi_headers_struct * TSRMLS_DC);
@@ -2029,7 +2030,7 @@ static int php_cli_server_dispatch(php_cli_server *server, php_cli_server_client
                        sapi_module.send_headers = send_header_func;
                    SG(sapi_headers).send_default_content_type = 1;
                        SG(rfc1867_uploaded_files) = NULL;
-               } 
+               }
                if (SUCCESS != php_cli_server_begin_send_static(server, client TSRMLS_CC)) {
                        php_cli_server_close_connection(server, client TSRMLS_CC);
                }
@@ -2191,6 +2192,8 @@ static int php_cli_server_recv_event_read_request(php_cli_server *server, php_cl
                efree(errstr);
                php_cli_server_close_connection(server, client TSRMLS_CC);
                return FAILURE;
+       } else if (status == 1 && client->request.request_method == PHP_HTTP_NOT_IMPLEMENTED) {
+               return php_cli_server_send_error_page(server, client, 501 TSRMLS_CC);
        } else if (status == 1) {
                php_cli_server_poller_remove(&server->poller, POLLIN, client->sock);
                php_cli_server_dispatch(server, client TSRMLS_CC);
@@ -2311,7 +2314,7 @@ static void php_cli_server_do_event_for_each_fd(php_cli_server *server, int(*rha
 static int php_cli_server_do_event_loop(php_cli_server *server TSRMLS_DC) /* {{{ */
 {
        int retval = SUCCESS;
-       while (server->is_running) {    
+       while (server->is_running) {
                static const struct timeval tv = { 1, 0 };
                int n = php_cli_server_poller_poll(&server->poller, &tv);
                if (n > 0) {
index 13b9ea12bcd1ab9eb955a9441443b8de4f08f2b0..4a95f8257546ee1933e609bef7d21201e30eab20 100644 (file)
@@ -99,6 +99,7 @@ static const char *method_strings[] =
   , "NOTIFY"
   , "SUBSCRIBE"
   , "UNSUBSCRIBE"
+  , "NOTIMPLEMENTED"
   };
 
 
@@ -589,7 +590,7 @@ size_t php_http_parser_execute (php_http_parser *parser,
           case 'S': parser->method = PHP_HTTP_SUBSCRIBE; break;
           case 'T': parser->method = PHP_HTTP_TRACE; break;
           case 'U': parser->method = PHP_HTTP_UNLOCK; /* or UNSUBSCRIBE */ break;
-          default: goto error;
+          default: parser->method = PHP_HTTP_NOT_IMPLEMENTED; break;
         }
         state = s_req_method;
         break;
@@ -602,7 +603,7 @@ size_t php_http_parser_execute (php_http_parser *parser,
           goto error;
 
         matcher = method_strings[parser->method];
-        if (ch == ' ' && matcher[index] == '\0') {
+        if (ch == ' ' && (matcher[index] == '\0' || parser->method == PHP_HTTP_NOT_IMPLEMENTED)) {
           state = s_req_spaces_before_url;
         } else if (ch == matcher[index]) {
           ; /* nada */
@@ -631,7 +632,7 @@ size_t php_http_parser_execute (php_http_parser *parser,
         } else if (index == 4 && parser->method == PHP_HTTP_PROPFIND && ch == 'P') {
           parser->method = PHP_HTTP_PROPPATCH;
         } else {
-          goto error;
+          parser->method = PHP_HTTP_NOT_IMPLEMENTED;
         }
 
         ++index;
index 7e72b78d7db9224735f0a29eb82e7bd04487f167..0f6c13dd354fb124b3ca6f6901ccaf6427b4ced1 100644 (file)
@@ -102,6 +102,8 @@ enum php_http_method
   , PHP_HTTP_NOTIFY
   , PHP_HTTP_SUBSCRIBE
   , PHP_HTTP_UNSUBSCRIBE
+  /* unknown, not implemented */
+  , PHP_HTTP_NOT_IMPLEMENTED
   };
 
 
diff --git a/sapi/cli/tests/bug61679.phpt b/sapi/cli/tests/bug61679.phpt
new file mode 100644 (file)
index 0000000..819ce2f
--- /dev/null
@@ -0,0 +1,43 @@
+--TEST--
+Bug #61679 (Error on non-standard HTTP methods)
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start(<<<'PHP'
+echo "This should never echo";
+PHP
+);
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+  die("connect failed");
+}
+
+// Send a request with a fictitious request method,
+// I like smurfs, the smurf everything.
+if(fwrite($fp, <<<HEADER
+SMURF / HTTP/1.1
+Host: {$host}
+
+
+HEADER
+)) {
+    while (!feof($fp)) {
+        echo fgets($fp);
+        // Only echo the first line from the response,
+        // the rest is not interesting
+        break;
+    }
+}
+
+fclose($fp);
+?>
+--EXPECTF--
+HTTP/1.1 501 Not Implemented