An HTTP request may contain the port number:

        $ nc -l 8080
        GET / HTTP/1.1
        Host: localhost:8080
        User-Agent: curl/7.55.1
        Accept: */*

It provoked the canonical host to mismatch while comparing it with
the actual host:

        r->field[REQ_HOST]: localhost:8080
        vhostmatch:         localhost

This commit fix it by replacing the ':' before the port by '\0'.
IPv6 addresses also have columns in the host name (RFC 2732):

        r->field[REQ_HOST]: [::1]
        vhostmatch:         [::1]
---
 http.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/http.c b/http.c
index 12ebde8..f3a596f 100644
--- a/http.c
+++ b/http.c
@@ -401,6 +401,14 @@ http_send_response(int fd, struct request *r)
                }
        }
 
+        /* check for IPv6 address (RFC 3986, 2732), then strip the port
+         * out of the host name */
+       if ((r->field[REQ_HOST][0] == '[' &&
+            (p = strchr(r->field[REQ_HOST], ']')) && *++p == ':') ||
+           (p = strchr(r->field[REQ_HOST], ':'))) {
+               *p = '\0';
+       }
+
        /* redirect if targets differ, host is non-canonical or we prefixed */
        if (strcmp(r->target, realtarget) || (s.vhost && vhostmatch &&
            strcmp(r->field[REQ_HOST], vhostmatch))) {
-- 
2.10.0


Reply via email to