]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-http: request-parser: Do not require Host header for HTTP/1.0 requests.
authorStephan Bosch <stephan.bosch@dovecot.fi>
Fri, 29 Jun 2018 10:52:28 +0000 (12:52 +0200)
committerStephan Bosch <stephan.bosch@dovecot.fi>
Mon, 2 Jul 2018 23:36:59 +0000 (01:36 +0200)
src/lib-http/http-request-parser.c
src/lib-http/test-http-request-parser.c

index 214e460cb52389f01619cb32581d0605d4cc1084..0862b623f418f25a048cdcb0bd4f407b8d1830aa 100644 (file)
@@ -529,7 +529,7 @@ int http_request_parse_next(struct http_request_parser *parser,
                            enum http_request_parse_error *error_code_r, const char **error_r)
 {
        const struct http_header_field *hdr;
-       const char *error;
+       const char *host_hdr, *error;
        int ret;
 
        /* initialize and get rid of any payload of previous request */
@@ -584,20 +584,26 @@ int http_request_parse_next(struct http_request_parser *parser,
           request message that contains more than one Host header field or a
           Host header field with an invalid field-value.
         */
-       if ((ret=http_header_field_find_unique
-               (parser->parser.msg.header, "Host", &hdr)) <= 0) {
-               *error_code_r = HTTP_REQUEST_PARSE_ERROR_BAD_REQUEST;
-               if (ret == 0)
-                       *error_r = "Missing Host header";
-               else
-                       *error_r = "Duplicate Host header";
-               return -1;
+       host_hdr = NULL;
+       if (parser->parser.msg.version_major == 1 &&
+           parser->parser.msg.version_minor > 0) {
+               if ((ret=http_header_field_find_unique(
+                       parser->parser.msg.header, "Host", &hdr)) <= 0) {
+                       *error_code_r = HTTP_REQUEST_PARSE_ERROR_BAD_REQUEST;
+                       if (ret == 0)
+                               *error_r = "Missing Host header";
+                       else
+                               *error_r = "Duplicate Host header";
+                       return -1;
+               }
+
+               host_hdr = hdr->value;
        }
 
        i_zero(request);
 
        pool = http_message_parser_get_pool(&parser->parser);
-       if (http_url_request_target_parse(parser->request_target, hdr->value,
+       if (http_url_request_target_parse(parser->request_target, host_hdr,
                parser->default_base_url, pool, &request->target, &error) < 0) {
                *error_code_r = HTTP_REQUEST_PARSE_ERROR_BAD_REQUEST;
                *error_r = t_strdup_printf("Bad request target `%s': %s",
index 92ddad4519fb89a12b4785936b59b52dcd6c0602..c71bb915bb8e701172ad1c20e4e3513b222d7c6e 100644 (file)
@@ -63,7 +63,18 @@ valid_request_parse_tests[] = {
                },
                .version_major = 1, .version_minor = 1,
        },{ .request =
-                       "OPTIONS * HTTP/1.0\r\n"
+                       "GET / HTTP/1.0\r\n"
+                       "\r\n",
+               .method = "GET",
+               .target_raw = "/",
+               .target = {
+                       .format = HTTP_REQUEST_TARGET_FORMAT_ORIGIN,
+                       .url = { .host = { .name = "example.org" } }
+               },
+               .version_major = 1, .version_minor = 0,
+               .connection_close = TRUE,
+       },{ .request =
+                       "OPTIONS * HTTP/1.1\r\n"
                        "Host: example.com\r\n"
                        "Connection: Keep-Alive\r\n"
                        "\r\n",
@@ -73,6 +84,17 @@ valid_request_parse_tests[] = {
                        .format = HTTP_REQUEST_TARGET_FORMAT_ASTERISK,
                        .url = { .host = { .name = "example.com" } }
                },
+               .version_major = 1, .version_minor = 1,
+       },{ .request =
+                       "OPTIONS * HTTP/1.0\r\n"
+                       "Connection: Keep-Alive\r\n"
+                       "\r\n",
+               .method = "OPTIONS",
+               .target_raw = "*",
+               .target = {
+                       .format = HTTP_REQUEST_TARGET_FORMAT_ASTERISK,
+                       .url = { .host = { .name = "example.org" } }
+               },
                .version_major = 1, .version_minor = 0,
        },{ .request =
                        "CONNECT example.com:443 HTTP/1.2\r\n"