]> granicus.if.org Git - apache/commitdiff
Perform correct, strict parsing of the request line, handling the
authorWilliam A. Rowe Jr <wrowe@apache.org>
Thu, 18 Aug 2016 07:15:06 +0000 (07:15 +0000)
committerWilliam A. Rowe Jr <wrowe@apache.org>
Thu, 18 Aug 2016 07:15:06 +0000 (07:15 +0000)
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.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1756729 13f79535-47bb-0310-9956-ffa450edef68

docs/manual/mod/core.xml
include/ap_mmn.h
include/http_core.h
server/core.c
server/protocol.c

index ae4b4ab0f871b445ed6e94088a7f8c20019ab01d..ee2f4aff351c35bee33b99526077686a1a8342ba 100644 (file)
@@ -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>
 
index a5936778633425190ff7c9725b853f6022ef7877..3c584f2ee9a8f79ea405942a051bd749f369b2bb 100644 (file)
  * 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
index 0a434d34aa3aa4df6f2ab6b523cfc215906dba01..1f3207e820ab4db508df2cb43806e1880c370b3c 100644 (file)
@@ -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
index a8c9634ef34490aac41d043459b3d4faf9b78ffb..943474ff20663ceffa0bc5468b36a1da922f1cf9 100644 (file)
@@ -533,6 +533,12 @@ static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv)
     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_options(cmd_parms *cmd, void *dummy,
     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;
 }
index a03ecf177df3ee722bdf3ec6908f205f29b082cb..ec466cb9b539d2f6581533511cd495e136aad060 100644 (file)
@@ -559,18 +559,32 @@ AP_CORE_DECLARE(void) ap_parse_uri(request_rec *r, const char *uri)
     }
 }
 
-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, apr_bucket_brigade *bb)
     }
 
     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);
 
-    if (!*r->method || !*uri) {
-        r->status    = HTTP_BAD_REQUEST;
-        r->proto_num = HTTP_VERSION(1,0);
-        r->protocol  = "HTTP/1.0";
-        return 0;
-    }
+    r->method = r->the_request;
+    if (apr_isspace(*r->method))
+        deferred_error = rrl_excesswhitespace; 
+    for ( ; apr_isspace(*r->method); ++r->method)
+        ; 
 
-    /* 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;
+    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 ");
+        }
     }
+    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;
+    }
+
+    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);
 
-    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 (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;
+        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);
     }
-
-    if (ll[0]) {
+    else if (r->protocol[0]) {
         r->assbackwards = 0;
-        pro = ll;
-        len = strlen(ll);
+        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");
+            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->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");
-            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 *r, apr_bucket_brigade *bb)
     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)
 {