]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-http: request-parser: Add support for empty Host header (default base url).
authorStephan Bosch <stephan.bosch@dovecot.fi>
Mon, 2 Jul 2018 18:17:51 +0000 (20:17 +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/http-request-parser.h
src/lib-http/http-server-connection.c
src/lib-http/test-http-request-parser.c

index 813b542aff67ebcbc9f3c8b685d6672644872460..214e460cb52389f01619cb32581d0605d4cc1084 100644 (file)
@@ -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);
index 841e28ab671e6007d4fb4b7132b4a62c504c8354..3956062924ddbb5c96b396480d402899ae9c3d57 100644 (file)
@@ -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(
index a3715ae2fd5e74a99a4713157be5ba0af1f5af2a..c2b6d0c8fb64261568896929f296ecf5f460f47a 100644 (file)
@@ -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);
 }
index e6f60de59027a4188779c4e07eae230e2b6cd072..92ddad4519fb89a12b4785936b59b52dcd6c0602 100644 (file)
@@ -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