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