]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-http: url: Add support for default base url to request target parsing.
authorStephan Bosch <stephan.bosch@dovecot.fi>
Mon, 2 Jul 2018 18:14:19 +0000 (20:14 +0200)
committerStephan Bosch <stephan.bosch@dovecot.fi>
Mon, 2 Jul 2018 23:36:53 +0000 (01:36 +0200)
src/lib-http/http-request-parser.c
src/lib-http/http-url.c
src/lib-http/http-url.h

index 93339248110f21c373875f681af49b5a8b6c1585..813b542aff67ebcbc9f3c8b685d6672644872460 100644 (file)
@@ -590,7 +590,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,
-               pool, &request->target, &error) < 0) {
+               NULL, 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 6815f2fcd0005d421ec05e76aacc5214f6c273d6..4cbbab8b1b8e54f27d92de988cf3afb122e58001 100644 (file)
@@ -352,43 +352,57 @@ int http_url_parse(const char *url, struct http_url *base,
 }
 
 int http_url_request_target_parse(const char *request_target,
-       const char *host_header, pool_t pool, struct http_request_target *target,
-       const char **error_r)
+                                 const char *host_header,
+                                 const struct http_url *default_base,
+                                 pool_t pool,
+                                 struct http_request_target *target,
+                                 const char **error_r)
 {
        struct http_url_parser url_parser;
-       struct uri_parser *parser;
        struct uri_authority auth;
        struct http_url base;
 
-       i_zero(&url_parser);
-       parser = &url_parser.parser;
-       uri_parser_init(parser, pool, host_header);
+       i_zero(&base);
+       if (host_header != NULL && *host_header != '\0') {
+               struct uri_parser *parser;
+               
+               i_zero(&url_parser);
+               parser = &url_parser.parser;
+               uri_parser_init(parser, pool, host_header);
+
+               if (uri_parse_host_authority(parser, &auth) <= 0) {
+                       *error_r = t_strdup_printf("Invalid Host header: %s",
+                                                  parser->error);
+                       return -1;
+               }
 
-       if (uri_parse_host_authority(parser, &auth) <= 0) {
-               *error_r = t_strdup_printf("Invalid Host header: %s", parser->error);
-               return -1;
-       }
+               if (parser->cur != parser->end || auth.enc_userinfo != NULL) {
+                       *error_r = "Invalid Host header: "
+                                  "Contains invalid character";
+                       return -1;
+               }
 
-       if (parser->cur != parser->end || auth.enc_userinfo != NULL) {
-               *error_r = "Invalid Host header: Contains invalid character";
+               base.host = auth.host;
+               base.port = auth.port;
+       } else if (default_base == NULL) {
+               *error_r = "Empty Host header";
                return -1;
+       } else {
+               i_assert(default_base != NULL);
+               base = *default_base;
        }
 
        if (request_target[0] == '*' && request_target[1] == '\0') {
                struct http_url *url = p_new(pool, struct http_url, 1);
-               uri_host_copy(pool, &url->host, &auth.host);
-               url->port = auth.port;
+               uri_host_copy(pool, &url->host, &base.host);
+               url->port = base.port;
                target->url = url;
                target->format = HTTP_REQUEST_TARGET_FORMAT_ASTERISK;
                return 0;
        }
 
-       i_zero(&base);
-       base.host = auth.host;
-       base.port = auth.port;
-
-       i_zero(parser);
-       uri_parser_init(parser, pool, request_target);
+       i_zero(&url_parser);
+       uri_parser_init(&url_parser.parser, pool, request_target);
 
        url_parser.url = p_new(pool, struct http_url, 1);
        url_parser.request_target = TRUE;
index 5eb311c8d83d4db7c7c5a4ad6a4a01056cd40da7..6ee91398529f75bf0afb68749a409341f90c8285 100644 (file)
@@ -50,8 +50,11 @@ int http_url_parse(const char *url, struct http_url *base,
                   struct http_url **url_r, const char **error_r);
 
 int http_url_request_target_parse(const char *request_target,
-       const char *host_header, pool_t pool,
-       struct http_request_target *target, const char **error_r);
+                                 const char *host_header,
+                                 const struct http_url *default_base,
+                                 pool_t pool,
+                                 struct http_request_target *target,
+                                 const char **error_r) ATTR_NULL(3);
 
 /*
  * HTTP URL evaluation