]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-http: server: Properly handle empty Host header by providing a default authority.
authorStephan Bosch <stephan.bosch@dovecot.fi>
Mon, 2 Jul 2018 18:19:34 +0000 (20:19 +0200)
committerStephan Bosch <stephan.bosch@dovecot.fi>
Mon, 2 Jul 2018 23:36:59 +0000 (01:36 +0200)
This behavior is required by the RFC.

src/lib-http/http-server-connection.c
src/lib-http/http-server.c
src/lib-http/http-server.h

index c2b6d0c8fb64261568896929f296ecf5f460f47a..eb4ebc2bc8c9743b1f3018c42f9b3a1a96d97c0d 100644 (file)
@@ -4,6 +4,7 @@
 #include "llist.h"
 #include "array.h"
 #include "str.h"
+#include "hostpid.h"
 #include "ioloop.h"
 #include "istream.h"
 #include "istream-timeout.h"
@@ -14,6 +15,7 @@
 #include "master-service.h"
 #include "master-service-ssl.h"
 #include "http-date.h"
+#include "http-url.h"
 #include "http-request-parser.h"
 
 #include "http-server-private.h"
@@ -160,6 +162,8 @@ bool http_server_connection_shut_down(struct http_server_connection *conn)
 
 static void http_server_connection_ready(struct http_server_connection *conn)
 {
+       const struct http_server_settings *set = &conn->server->set;
+       struct http_url base_url;
        struct stat st;
 
        if (conn->server->set.rawlog_dir != NULL &&
@@ -168,8 +172,18 @@ static void http_server_connection_ready(struct http_server_connection *conn)
                                       &conn->conn.input, &conn->conn.output);
        }
 
+       i_zero(&base_url);
+       if (set->default_host != NULL)
+               base_url.host.name = set->default_host;
+       else if (conn->ip.family != 0)
+               base_url.host.ip = conn->ip;
+       else
+               base_url.host.name = my_hostname;
+       base_url.port = conn->port;
+       base_url.have_ssl = conn->ssl;
+
        conn->http_parser = http_request_parser_init(
-               conn->conn.input, NULL, &conn->server->set.request_limits,
+               conn->conn.input, &base_url, &conn->server->set.request_limits,
                HTTP_REQUEST_PARSE_FLAG_STRICT);
        o_stream_set_flush_callback(conn->conn.output,
     http_server_connection_output, conn);
index 747d424902c55d0f88e0a677292a1952145eac0b..e94b29b4f386202fe03cba1cfa0dd8e7653ecaaa 100644 (file)
@@ -28,6 +28,9 @@ struct http_server *http_server_init(const struct http_server_settings *set)
        pool = pool_alloconly_create("http server", 1024);
        server = p_new(pool, struct http_server, 1);
        server->pool = pool;
+
+       if (set->default_host != NULL && *set->default_host != '\0')
+               server->set.default_host = p_strdup(pool, set->default_host);
        if (set->rawlog_dir != NULL && *set->rawlog_dir != '\0')
                server->set.rawlog_dir = p_strdup(pool, set->rawlog_dir);
        if (set->ssl != NULL) {
index 8e8009cf8d3c9a162fa655491990b50646b28b69..3fc45176ff9db34731bb65230bc18b6ea3bafc0e 100644 (file)
@@ -19,6 +19,8 @@ struct http_server_response;
  */
 
 struct http_server_settings {
+       const char *default_host;
+
        const char *rawlog_dir;
 
        /* SSL settings; if NULL, master_service_ssl_init() is used instead */