httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wr...@apache.org
Subject svn commit: r1756729 - in /httpd/httpd/trunk: docs/manual/mod/core.xml include/ap_mmn.h include/http_core.h server/core.c server/protocol.c
Date Thu, 18 Aug 2016 07:15:07 GMT
Author: wrowe
Date: Thu Aug 18 07:15:06 2016
New Revision: 1756729

URL: http://svn.apache.org/viewvc?rev=1756729&view=rev
Log:
Perform correct, strict parsing of the request line, handling the
http protocol tag, url and method appropriately, and attempting 
to extract values even in the presence of unusual whitespace in
keeping with section 3.5, prior to responding with whatever
error reply is needed. Conforms to RFC7230 in all respects,
the section 3.5 optional behavior can be disabled by the user
with a new HttpProtocolOptions StrictWhitespace flag. In all
cases, the_request is regenerated from the parsed components
with exactly two space characters.

Shift sf's 'strict' method check from the Strict behavior because
it violates forward proxy logic, adding a new RegisteredMethods
flag, as it will certainly be useful to some.



Modified:
    httpd/httpd/trunk/docs/manual/mod/core.xml
    httpd/httpd/trunk/include/ap_mmn.h
    httpd/httpd/trunk/include/http_core.h
    httpd/httpd/trunk/server/core.c
    httpd/httpd/trunk/server/protocol.c

Modified: httpd/httpd/trunk/docs/manual/mod/core.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/core.xml?rev=1756729&r1=1756728&r2=1756729&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/core.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/core.xml Thu Aug 18 07:15:06 2016
@@ -1252,8 +1252,10 @@ EnableSendfile On
 <directivesynopsis>
 <name>HTTPProtocolOptions</name>
 <description>Modify restrictions on HTTP Request Messages</description>
-<syntax>HTTPProtocolOptions [Strict|Unsafe] [Allow0.9|Require1.0]</syntax>
-<default>HTTPProtocolOptions Strict Allow0.9</default>
+<syntax>HTTPProtocolOptions [Strict|Unsafe] [Allow0.9|Require1.0] 
+[StrictWhitespace|LenientWhitespace] [RegisteredMethods|LenientMethods]</syntax>
+<default>HTTPProtocolOptions Strict Allow0.9 LenientWhitespace 
+LenientMethods</default>
 <contextlist><context>server config</context>
 <context>virtual host</context></contextlist>
 <compatibility>2.2.32 or 2.4.24 and later</compatibility>
@@ -1300,6 +1302,31 @@ EnableSendfile On
       >RFC 2616 Appendix A</a>. The <code>Require1.0</code> option allows
     the user to remove support of the default <code>Allow0.9</code> option's
     behavior.</p>
+
+    <p><a href="https://tools.ietf.org/html/rfc7230#section-3.5"
+         >RFC 7230 &sect;3.5</a> "Message Parsing Robustness" permits, and
+    identifies potential risks of parsing messages containing non-space
+    character whitespace. While the spec defines that exactly one space
+    seperates the URI from the method, and the protocol from the URI, the
+    Apache HTTP Server has traditionally been lenient in accepting other
+    whitespace including one or more horizontal-tab or space characters.
+    The default <code>LenientWhitespace</code> continues to accept such
+    requests from non-conforming user-agents, but the administrator may toggle
+    the <code>StrictWhitespace</code> option to insist on precisely two spaces
+    in the request line. Other whitespace including vertical-tab, form-feed,
+    and carriage-return characters are rejected and cannot be supported.</p>
+
+    <p><a href="https://tools.ietf.org/html/rfc7231#section-4.1"
+         >RFC 7231 &sect;4.1</a> "Request Methods" "Overview" requires that
+    origin servers shall respond with an error when an unsupported method
+    is encountered in the request line. This already happens when the
+    <code>LenientMethods</code> option is used, but administrators may wish
+    to toggle the <code>RegisteredMethods</code> option and register all
+    permitted method tokens using the <directive>RegisterHttpMethod</directive>
+    directive, particularly if the <code>Unsafe</code> option has been toggled.
+    The <code>RegisteredMethods</code> option should <strong>not</strong>
+    be toggled for forward proxy hosts, as the methods supported by the
+    origin servers are unknown to the proxy server.</p>
 </usage>
 </directivesynopsis>
 

Modified: httpd/httpd/trunk/include/ap_mmn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/ap_mmn.h?rev=1756729&r1=1756728&r2=1756729&view=diff
==============================================================================
--- httpd/httpd/trunk/include/ap_mmn.h (original)
+++ httpd/httpd/trunk/include/ap_mmn.h Thu Aug 18 07:15:06 2016
@@ -542,14 +542,16 @@
  * 20160608.9 (2.5.0-dev)  Renamed AP_HTTP_CONFORMANCE_LIBERAL to 
  *                         AP_HTTP_CONFORMANCE_UNSAFE, and
  *                         eliminated AP_HTTP_CONFORMANCE_LOGONLY
+ * 20160617.1 (2.5.0-dev)  Added http_whitespace and http_methods to
+ *                         core_server_config
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
 
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
-#define MODULE_MAGIC_NUMBER_MAJOR 20160608
+#define MODULE_MAGIC_NUMBER_MAJOR 20160617
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 9                 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 1                 /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a

Modified: httpd/httpd/trunk/include/http_core.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/http_core.h?rev=1756729&r1=1756728&r2=1756729&view=diff
==============================================================================
--- httpd/httpd/trunk/include/http_core.h (original)
+++ httpd/httpd/trunk/include/http_core.h Thu Aug 18 07:15:06 2016
@@ -739,6 +739,16 @@ typedef struct {
 #define AP_HTTP_CONFORMANCE_STRICT    2
     char http_conformance;
 
+#define AP_HTTP_WHITESPACE_UNSET      0
+#define AP_HTTP_WHITESPACE_LENIENT    1
+#define AP_HTTP_WHITESPACE_STRICT     2
+    char http_whitespace;
+
+#define AP_HTTP_METHODS_UNSET         0
+#define AP_HTTP_METHODS_LENIENT       1
+#define AP_HTTP_METHODS_REGISTERED    2
+    char http_methods;
+
 #define AP_HTTP_CL_HEAD_ZERO_UNSET    0
 #define AP_HTTP_CL_HEAD_ZERO_ENABLE   1
 #define AP_HTTP_CL_HEAD_ZERO_DISABLE  2

Modified: httpd/httpd/trunk/server/core.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/core.c?rev=1756729&r1=1756728&r2=1756729&view=diff
==============================================================================
--- httpd/httpd/trunk/server/core.c (original)
+++ httpd/httpd/trunk/server/core.c Thu Aug 18 07:15:06 2016
@@ -533,6 +533,12 @@ static void *merge_core_server_configs(a
     if (virt->http_conformance != AP_HTTP_CONFORMANCE_UNSET)
         conf->http_conformance = virt->http_conformance;
 
+    if (virt->http_whitespace != AP_HTTP_WHITESPACE_UNSET)
+        conf->http_whitespace = virt->http_whitespace;
+
+    if (virt->http_methods != AP_HTTP_METHODS_UNSET)
+        conf->http_methods = virt->http_methods;
+
     if (virt->http_cl_head_zero != AP_HTTP_CL_HEAD_ZERO_UNSET)
         conf->http_cl_head_zero = virt->http_cl_head_zero;
 
@@ -4017,34 +4023,47 @@ static const char *set_http_protocol_opt
     core_server_config *conf =
         ap_get_core_module_config(cmd->server->module_config);
 
-    if (strcasecmp(arg, "allow0.9") == 0) {
+    if (strcasecmp(arg, "allow0.9") == 0)
         conf->http09_enable |= AP_HTTP09_ENABLE;
-    }
-    else if (strcasecmp(arg, "require1.0") == 0) {
+    else if (strcasecmp(arg, "require1.0") == 0)
         conf->http09_enable |= AP_HTTP09_DISABLE;
-    }
-    else if (strcasecmp(arg, "strict") == 0) {
+    else if (strcasecmp(arg, "strict") == 0)
         conf->http_conformance |= AP_HTTP_CONFORMANCE_STRICT;
-    }
-    else if (strcasecmp(arg, "unsafe") == 0) {
+    else if (strcasecmp(arg, "unsafe") == 0)
         conf->http_conformance |= AP_HTTP_CONFORMANCE_UNSAFE;
-    }
-    else {
-        return "HttpProtocolOptions accepts 'Allow0.9' (default), 'Require1.0',"
-               " 'Unsafe', or 'Strict' (default)";
-    }
+    else if (strcasecmp(arg, "strictwhitespace") == 0)
+        conf->http_whitespace |= AP_HTTP_WHITESPACE_STRICT;
+    else if (strcasecmp(arg, "lenientwhitespace") == 0)
+        conf->http_whitespace |= AP_HTTP_WHITESPACE_LENIENT;
+    else if (strcasecmp(arg, "registeredmethods") == 0)
+        conf->http_methods |= AP_HTTP_METHODS_REGISTERED;
+    else if (strcasecmp(arg, "lenientmethods") == 0)
+        conf->http_methods |= AP_HTTP_METHODS_LENIENT;
+    else
+        return "HttpProtocolOptions accepts 'Allow0.9' (default) or "
+               "'Require1.0', 'Unsafe' or 'Strict' (default), "
+               "'StrictWhitespace' or 'LenientWhitespace (default), and "
+               "'RegisteredMethods' or 'LenientMethods (default)";
 
-    if ((conf->http09_enable & AP_HTTP09_ENABLE) &&
-        (conf->http09_enable & AP_HTTP09_DISABLE)) {
+    if ((conf->http09_enable & AP_HTTP09_ENABLE)
+            && (conf->http09_enable & AP_HTTP09_DISABLE))
         return "HttpProtocolOptions 'Allow0.9' and 'Require1.0'"
                " are mutually exclusive";
-    }
 
-    if ((conf->http_conformance & AP_HTTP_CONFORMANCE_STRICT) &&
-        (conf->http_conformance & AP_HTTP_CONFORMANCE_UNSAFE)) {
+    if ((conf->http_conformance & AP_HTTP_CONFORMANCE_STRICT)
+            && (conf->http_conformance & AP_HTTP_CONFORMANCE_UNSAFE))
         return "HttpProtocolOptions 'Strict' and 'Unsafe'"
                " are mutually exclusive";
-    }
+
+    if ((conf->http_whitespace & AP_HTTP_WHITESPACE_STRICT)
+            && (conf->http_whitespace & AP_HTTP_WHITESPACE_LENIENT))
+        return "HttpProtocolOptions 'StrictWhitespace' and 'LenientWhitespace'"
+               " are mutually exclusive";
+
+    if ((conf->http_methods & AP_HTTP_METHODS_REGISTERED)
+            && (conf->http_methods & AP_HTTP_METHODS_LENIENT))
+        return "HttpProtocolOptions 'RegisteredMethods' and 'LenientMethods'"
+               " are mutually exclusive";
 
     return NULL;
 }

Modified: httpd/httpd/trunk/server/protocol.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/protocol.c?rev=1756729&r1=1756728&r2=1756729&view=diff
==============================================================================
--- httpd/httpd/trunk/server/protocol.c (original)
+++ httpd/httpd/trunk/server/protocol.c Thu Aug 18 07:15:06 2016
@@ -559,18 +559,32 @@ AP_CORE_DECLARE(void) ap_parse_uri(reque
     }
 }
 
-static int read_request_line(request_rec *r, apr_bucket_brigade *bb)
+/* get the length of the field name for logging, but no more than 80 bytes */
+#define LOG_NAME_MAX_LEN 80
+static int field_name_len(const char *field)
 {
-    const char *ll;
-    const char *uri;
-    const char *pro;
+    const char *end = ap_strchr_c(field, ':');
+    if (end == NULL || end - field > LOG_NAME_MAX_LEN)
+        return LOG_NAME_MAX_LEN;
+    return end - field;
+}
 
+static int read_request_line(request_rec *r, apr_bucket_brigade *bb)
+{
+    enum {
+        rrl_none, rrl_badmethod, rrl_badwhitespace, rrl_excesswhitespace,
+        rrl_missinguri, rrl_badprotocol, rrl_trailingtext
+    } deferred_error = rrl_none;
+    char *ll;
+    char *uri;
     unsigned int major = 1, minor = 0;   /* Assume HTTP/1.0 if non-"HTTP" protocol */
     char http[5];
     apr_size_t len;
     int num_blank_lines = DEFAULT_LIMIT_BLANK_LINES;
     core_server_config *conf = ap_get_core_module_config(r->server->module_config);
     int strict = (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE);
+    const char *badwhitespace = strict ? "\t\n\v\f\r" : "\n\v\f\r";
+    int strictspaces = (conf->http_whitespace == AP_HTTP_WHITESPACE_STRICT);
 
     /* Read past empty lines until we get a real request line,
      * a read error, the connection closes (EOF), or we timeout.
@@ -626,111 +640,211 @@ static int read_request_line(request_rec
     }
 
     r->request_time = apr_time_now();
-    ll = r->the_request;
-    r->method = ap_getword_white(r->pool, &ll);
 
-    uri = ap_getword_white(r->pool, &ll);
+    r->method = r->the_request;
+    if (apr_isspace(*r->method))
+        deferred_error = rrl_excesswhitespace; 
+    for ( ; apr_isspace(*r->method); ++r->method)
+        ; 
 
-    if (!*r->method || !*uri) {
-        r->status    = HTTP_BAD_REQUEST;
-        r->proto_num = HTTP_VERSION(1,0);
-        r->protocol  = "HTTP/1.0";
-        return 0;
+    if (strict) {
+        ll = (char*) ap_scan_http_token(r->method);
+        if ((ll == r->method) || (*ll && !apr_isspace(*ll))) {
+            deferred_error = rrl_badmethod;
+            ll = strpbrk(ll, "\t\n\v\f\r ");
+        }
     }
-
-    /* Provide quick information about the request method as soon as known */
-
-    r->method_number = ap_method_number_of(r->method);
-    if (r->method_number == M_GET && r->method[0] == 'H') {
-        r->header_only = 1;
+    else {
+        ll = strpbrk(r->method, "\t\n\v\f\r ");
+    }
+    if (!ll) {
+        if (deferred_error == rrl_none)
+            deferred_error = rrl_missinguri;
+        r->protocol = uri = "";
+        len = 0;
+        goto rrl_done;
     }
 
-    ap_parse_uri(r, uri);
-    if (r->status != HTTP_OK) {
-        r->proto_num = HTTP_VERSION(1,0);
-        r->protocol  = "HTTP/1.0";
-        return 0;
+    if (strictspaces && ll[0] && (ll[0] != ' ' || apr_isspace(ll[1]))
+            && deferred_error == rrl_none) {
+        deferred_error = rrl_excesswhitespace; 
+    }
+    for (uri = ll; apr_isspace(*uri); ++uri) 
+        if (strchr(badwhitespace, *uri) && deferred_error == rrl_none)
+            deferred_error = rrl_badwhitespace; 
+    *ll = '\0';
+    if (!*uri && deferred_error == rrl_none)
+        deferred_error = rrl_missinguri;
+
+    if (!(ll = strpbrk(uri, " \t\n\v\f\r"))) {
+        r->protocol = "";
+        len = 0;
+        goto rrl_done;
+    }
+    for (r->protocol = ll; apr_isspace(*r->protocol); ++r->protocol) 
+        if (strchr(badwhitespace, *r->protocol) && deferred_error == rrl_none
+                && deferred_error == rrl_none)
+            deferred_error = rrl_badwhitespace; 
+    *ll = '\0';
+    if (!(ll = strpbrk(r->protocol, " \t\n\v\f\r"))) {
+        len = strlen(r->protocol);
+        goto rrl_done;
     }
+    len = ll - r->protocol;
+    if (strictspaces && *ll)
+        deferred_error = rrl_excesswhitespace; 
+    for ( ; apr_isspace(*ll); ++ll)
+        if (strchr(badwhitespace, *ll) && deferred_error == rrl_none)
+            deferred_error = rrl_badwhitespace; 
+    if (*ll && deferred_error == rrl_none)
+        deferred_error = rrl_trailingtext;
+    ll = (char *)r->protocol + len;
+    *ll = '\0';
+
+rrl_done:
+    /* For internal integrety, reconstruct the_request
+     * using only single SP characters, per spec.
+     * Once the method, uri and protocol are processed,
+     * we can then resume deferred error reporting
+     */
+    r->the_request = apr_pstrcat(r->pool, r->method, *uri ? " " : NULL, uri,
+                                 *r->protocol ? " " : NULL, r->protocol, NULL);
 
-    if (ll[0]) {
+    if (len == 8
+            && r->protocol[0] == 'H' && r->protocol[1] == 'T'
+            && r->protocol[2] == 'T' && r->protocol[3] == 'P'
+            && r->protocol[4] == '/' && apr_isdigit(r->protocol[5])
+            && r->protocol[6] == '.' && apr_isdigit(r->protocol[7])
+            && r->protocol[5] != '0') {
         r->assbackwards = 0;
-        pro = ll;
-        len = strlen(ll);
+        r->proto_num = HTTP_VERSION(r->protocol[5] - '0', r->protocol[7] - '0');
+    }
+    else if (len == 8
+                 && (r->protocol[0] == 'H' || r->protocol[0] == 'h')
+                 && (r->protocol[1] == 'T' || r->protocol[1] == 't')
+                 && (r->protocol[2] == 'T' || r->protocol[2] == 't')
+                 && (r->protocol[3] == 'P' || r->protocol[3] == 'p')
+                 && r->protocol[4] == '/' && apr_isdigit(r->protocol[5])
+                 && r->protocol[6] == '.' && apr_isdigit(r->protocol[7])
+                 && r->protocol[5] != '0') {
+        r->assbackwards = 0;
+        r->proto_num = HTTP_VERSION(r->protocol[5] - '0', r->protocol[7] - '0');
+        if (strict && deferred_error == rrl_none)
+            deferred_error = rrl_badprotocol;
+        else
+            memcpy((char*)r->protocol, "HTTP", 4);
+    }
+    else if (r->protocol[0]) {
+        r->assbackwards = 0;
+        r->proto_num = HTTP_VERSION(1,0);
+        /* Defer setting the r->protocol string till error msg is composed */
+        if (strict && deferred_error == rrl_none)
+            deferred_error = rrl_badprotocol;
+        else
+            r->protocol  = "HTTP/1.0";
     }
     else {
         r->assbackwards = 1;
-        pro = "HTTP/0.9";
-        len = 8;
-        if (conf->http09_enable == AP_HTTP09_DISABLE) {
-                r->status = HTTP_VERSION_NOT_SUPPORTED;
-                r->protocol = apr_pstrmemdup(r->pool, pro, len);
-                /* If we deny 0.9, send error message with 1.x */
-                r->assbackwards = 0;
-                r->proto_num = HTTP_VERSION(0, 9);
-                r->connection->keepalive = AP_CONN_CLOSE;
-                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02401)
-                              "HTTP/0.9 denied by server configuration");
-                return 0;
-        }
+        r->protocol = "HTTP/0.9";
+        r->proto_num = HTTP_VERSION(0, 9);
     }
-    r->protocol = apr_pstrmemdup(r->pool, pro, len);
 
-    /* Avoid sscanf in the common case */
-    if (len == 8
-        && pro[0] == 'H' && pro[1] == 'T' && pro[2] == 'T' &&
pro[3] == 'P'
-        && pro[4] == '/' && apr_isdigit(pro[5]) && pro[6] == '.'
-        && apr_isdigit(pro[7])) {
-        r->proto_num = HTTP_VERSION(pro[5] - '0', pro[7] - '0');
-    }
-    else {
-        if (strict) {
-            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02418)
-                          "Invalid protocol '%s'", r->protocol);
-            r->proto_num = HTTP_VERSION(1,0);
-            r->protocol  = "HTTP/1.0";
+    /* Satisfy the method_number and uri fields prior to invoking error
+     * handling, such that these fields are available for subsitution
+     */
+    r->method_number = ap_method_number_of(r->method);
+    if (r->method_number == M_GET && r->method[0] == 'H')
+        r->header_only = 1;
+
+    ap_parse_uri(r, uri);
+
+    if (r->proto_num == HTTP_VERSION(0, 9)) {
+        if (conf->http09_enable == AP_HTTP09_DISABLE
+                && deferred_error == rrl_none) {
+            /* If we deny 0.9, send error message with 1.x behavior */
+            r->assbackwards = 0;
             r->connection->keepalive = AP_CONN_CLOSE;
-            r->status = HTTP_BAD_REQUEST;
+            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02401)
+                          "HTTP Request Line; Rejected HTTP/0.9 request");
+            r->status = HTTP_VERSION_NOT_SUPPORTED;
             return 0;
         }
-        if (3 == sscanf(r->protocol, "%4s/%u.%u", http, &major, &minor)
-            && (ap_cstr_casecmp("http", http) == 0)
-            && (minor < HTTP_VERSION(1, 0)) ) { /* don't allow HTTP/0.1000 */
-            r->proto_num = HTTP_VERSION(major, minor);
+        if (strict && strcmp(r->method, "GET") && deferred_error == rrl_none)
{
+            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03444)
+                          "HTTP Request Line; Invalid method token: '%.*s'"
+                          " (only GET is allowed for HTTP/0.9 requests)",
+                          field_name_len(r->method), r->method);
+            r->status = HTTP_BAD_REQUEST;
+            return 0;
         }
-        else {
-            r->proto_num = HTTP_VERSION(1, 0);
+    }
+
+    if (deferred_error != rrl_none) {
+        if (deferred_error == rrl_badmethod)
+            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03445)
+                          "HTTP Request Line; Invalid method token: '%.*s'",
+                          field_name_len(r->method), r->method);
+        else if (deferred_error == rrl_missinguri)
+            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03446)
+                          "HTTP Request Line; Missing URI");
+        else if (deferred_error == rrl_badwhitespace)
+            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03447)
+                          "HTTP Request Line; Invalid whitespace");
+        else if (deferred_error == rrl_excesswhitespace)
+            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03448)
+                          "HTTP Request Line; Inappropriate whitespace "
+                          "(disallowed by StrictWhitespace");
+        else if (deferred_error == rrl_trailingtext)
+            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03449)
+                          "HTTP Request Line; Extraneous text found '%.*s' "
+                          "(perhaps whitespace was injected?)",
+                          field_name_len(ll), ll);
+        else if (deferred_error == rrl_badprotocol) {
+            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02418)
+                          "HTTP Request Line; Unrecognized protocol '%.*s' "
+                          "(perhaps whitespace was injected?)",
+                          field_name_len(r->protocol), r->protocol);
+            r->protocol  = "HTTP/1.0";
         }
+        r->status = HTTP_BAD_REQUEST;
+        return 0;
+    }
+
+    if (conf->http_methods == AP_HTTP_METHODS_REGISTERED
+            && r->method_number == M_INVALID) {
+        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02423)
+                      "HTTP Request Line; Unrecognized HTTP method: '%.*s' "
+                      "(disallowed by RegisteredMethods)",
+                      field_name_len(r->method), r->method);
+        r->status = HTTP_NOT_IMPLEMENTED;
+        return 0;
+    }
+
+    if (r->status != HTTP_OK) {
+        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(03450)
+                      "HTTP Request Line; URI parsing failed");
+        return 0;
     }
 
     if (strict) {
         if (ap_has_cntrl(r->the_request)) {
-            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02420)
-                          "Request line must not contain control characters");
+            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02420)
+                          "HTTP Request Line; URI must not contain control"
+                          " characters");
             r->status = HTTP_BAD_REQUEST;
             return 0;
         }
         if (r->parsed_uri.fragment) {
             /* RFC3986 3.5: no fragment */
-            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02421)
-                          "URI must not contain a fragment");
-            r->status = HTTP_BAD_REQUEST;
-            return 0;
-        }
-        else if (r->parsed_uri.user || r->parsed_uri.password) {
-            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02422)
-                          "URI must not contain a username/password");
+            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02421)
+                          "HTTP Request Line; URI must not contain a fragment");
             r->status = HTTP_BAD_REQUEST;
             return 0;
         }
-        else if (r->method_number == M_INVALID) {
-            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02423)
-                          "Invalid HTTP method string: %s", r->method);
-            r->status = HTTP_NOT_IMPLEMENTED;
-            return 0;
-        }
-        else if (r->assbackwards == 0 && r->proto_num < HTTP_VERSION(1,
0)) {
-            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02424)
-                          "HTTP/0.x does not take a protocol");
+        if (r->parsed_uri.user || r->parsed_uri.password) {
+            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02422)
+                          "HTTP Request Line; URI must not contain a "
+                          "username/password");
             r->status = HTTP_BAD_REQUEST;
             return 0;
         }
@@ -739,16 +853,6 @@ static int read_request_line(request_rec
     return 1;
 }
 
-/* get the length of the field name for logging, but no more than 80 bytes */
-#define LOG_NAME_MAX_LEN 80
-static int field_name_len(const char *field)
-{
-    const char *end = ap_strchr_c(field, ':');
-    if (end == NULL || end - field > LOG_NAME_MAX_LEN)
-        return LOG_NAME_MAX_LEN;
-    return end - field;
-}
-
 static int table_do_fn_check_lengths(void *r_, const char *key,
                                      const char *value)
 {



Mime
View raw message