From: Stephan Bosch Date: Mon, 2 Jul 2018 18:17:51 +0000 (+0200) Subject: lib-http: request-parser: Add support for empty Host header (default base url). X-Git-Tag: 2.3.9~1637 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=aea983327e9d2ef08e45f6a4cf8c17ad98b9160f;p=thirdparty%2Fdovecot%2Fcore.git lib-http: request-parser: Add support for empty Host header (default base url). --- diff --git a/src/lib-http/http-request-parser.c b/src/lib-http/http-request-parser.c index 813b542aff..214e460cb5 100644 --- a/src/lib-http/http-request-parser.c +++ b/src/lib-http/http-request-parser.c @@ -28,6 +28,8 @@ struct http_request_parser { enum http_request_parser_state state; + struct http_url *default_base_url; + uoff_t max_target_length; enum http_request_parse_error error_code; @@ -40,8 +42,9 @@ struct http_request_parser { struct http_request_parser * http_request_parser_init(struct istream *input, - const struct http_request_limits *limits, - enum http_request_parse_flags flags) + const struct http_url *default_base_url, + const struct http_request_limits *limits, + enum http_request_parse_flags flags) { struct http_request_parser *parser; pool_t pool; @@ -52,7 +55,12 @@ http_request_parser_init(struct istream *input, pool = pool_alloconly_create("http request parser", 512); parser = p_new(pool, struct http_request_parser, 1); parser->pool = pool; - + + if (default_base_url != NULL) { + parser->default_base_url = + http_url_clone_authority(pool, default_base_url); + } + if (limits != NULL) { hdr_limits = limits->header; max_payload_size = limits->max_payload_size; @@ -590,7 +598,7 @@ int http_request_parse_next(struct http_request_parser *parser, pool = http_message_parser_get_pool(&parser->parser); if (http_url_request_target_parse(parser->request_target, hdr->value, - NULL, pool, &request->target, &error) < 0) { + 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", parser->request_target, error); diff --git a/src/lib-http/http-request-parser.h b/src/lib-http/http-request-parser.h index 841e28ab67..3956062924 100644 --- a/src/lib-http/http-request-parser.h +++ b/src/lib-http/http-request-parser.h @@ -24,8 +24,9 @@ enum http_request_parse_flags { struct http_request_parser * http_request_parser_init(struct istream *input, - const struct http_request_limits *limits, - enum http_request_parse_flags flags) ATTR_NULL(2); + const struct http_url *default_base_url, + const struct http_request_limits *limits, + enum http_request_parse_flags flags) ATTR_NULL(2); void http_request_parser_deinit(struct http_request_parser **_parser); int http_request_parse_finish_payload( diff --git a/src/lib-http/http-server-connection.c b/src/lib-http/http-server-connection.c index a3715ae2fd..c2b6d0c8fb 100644 --- a/src/lib-http/http-server-connection.c +++ b/src/lib-http/http-server-connection.c @@ -168,9 +168,9 @@ static void http_server_connection_ready(struct http_server_connection *conn) &conn->conn.input, &conn->conn.output); } - conn->http_parser = http_request_parser_init - (conn->conn.input, &conn->server->set.request_limits, - HTTP_REQUEST_PARSE_FLAG_STRICT); + conn->http_parser = http_request_parser_init( + conn->conn.input, NULL, &conn->server->set.request_limits, + HTTP_REQUEST_PARSE_FLAG_STRICT); o_stream_set_flush_callback(conn->conn.output, http_server_connection_output, conn); } diff --git a/src/lib-http/test-http-request-parser.c b/src/lib-http/test-http-request-parser.c index e6f60de590..92ddad4519 100644 --- a/src/lib-http/test-http-request-parser.c +++ b/src/lib-http/test-http-request-parser.c @@ -34,6 +34,10 @@ struct http_request_valid_parse_test { enum http_request_parse_flags flags; }; +static const struct http_url default_base_url = { + .host = { .name = "example.org" }, +}; + static const struct http_request_valid_parse_test valid_request_parse_tests[] = { { .request = @@ -47,6 +51,17 @@ valid_request_parse_tests[] = { .url = { .host = { .name = "example.com" } } }, .version_major = 1, .version_minor = 1, + },{ .request = + "GET / HTTP/1.1\r\n" + "Host: \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 = 1, },{ .request = "OPTIONS * HTTP/1.0\r\n" "Host: example.com\r\n" @@ -209,7 +224,8 @@ static void test_http_request_parse_valid(void) request_text = test->request; request_text_len = strlen(request_text); input = test_istream_create_data(request_text, request_text_len); - parser = http_request_parser_init(input, NULL, test->flags); + parser = http_request_parser_init(input, &default_base_url, + NULL, test->flags); test_begin(t_strdup_printf("http request valid [%d]", i)); @@ -448,7 +464,8 @@ static void test_http_request_parse_invalid(void) test = &invalid_request_parse_tests[i]; request_text = test->request; input = i_stream_create_from_data(request_text, strlen(request_text)); - parser = http_request_parser_init(input, NULL, test->flags); + parser = http_request_parser_init(input, &default_base_url, + NULL, test->flags); i_stream_unref(&input); test_begin(t_strdup_printf("http request invalid [%d]", i)); @@ -490,8 +507,8 @@ static void test_http_request_parse_bad(void) test_begin("http request with NULs (strict)"); input = i_stream_create_from_data(bad_request_with_nuls, sizeof(bad_request_with_nuls)-1); - parser = http_request_parser_init(input, NULL, - HTTP_REQUEST_PARSE_FLAG_STRICT); + parser = http_request_parser_init(input, &default_base_url, NULL, + HTTP_REQUEST_PARSE_FLAG_STRICT); i_stream_unref(&input); while ((ret=http_request_parse_next @@ -504,7 +521,7 @@ static void test_http_request_parse_bad(void) test_begin("http request with NULs (lenient)"); input = i_stream_create_from_data(bad_request_with_nuls, sizeof(bad_request_with_nuls)-1); - parser = http_request_parser_init(input, NULL, 0); + parser = http_request_parser_init(input, &default_base_url, NULL, 0); i_stream_unref(&input); ret = http_request_parse_next