From: Stephan Bosch Date: Fri, 29 Jun 2018 10:52:28 +0000 (+0200) Subject: lib-http: request-parser: Do not require Host header for HTTP/1.0 requests. X-Git-Tag: 2.3.9~1635 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=057490a88f69faf8bdf78b1b5924d796e411ce33;p=thirdparty%2Fdovecot%2Fcore.git lib-http: request-parser: Do not require Host header for HTTP/1.0 requests. --- diff --git a/src/lib-http/http-request-parser.c b/src/lib-http/http-request-parser.c index 214e460cb5..0862b623f4 100644 --- a/src/lib-http/http-request-parser.c +++ b/src/lib-http/http-request-parser.c @@ -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", diff --git a/src/lib-http/test-http-request-parser.c b/src/lib-http/test-http-request-parser.c index 92ddad4519..c71bb915bb 100644 --- a/src/lib-http/test-http-request-parser.c +++ b/src/lib-http/test-http-request-parser.c @@ -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"