Tags: +patch Hi,
I'm attaching a patch, tested, that is the simplest solution I can think of. Colons found between square brackets are now preserved. If a closing square bracket is not found, such as in '[::', this now returns 400 Bad Request, in line with the behaviour observed in Apache. At this time, the IPv6 address is not sanitised in any way, I just did the minimal change possible to fix the bug I've been seeing. Regards, -- Steven Chamberlain ste...@pyro.eu.org
diff -Nru a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c 2010-06-07 11:14:11.000000000 +0100 +++ b/src/http/ngx_http_request.c 2010-12-18 07:42:29.000000000 +0000 @@ -1645,11 +1645,12 @@ { u_char *h, ch; size_t i, last; - ngx_uint_t dot; + ngx_uint_t dot, in_brackets; last = len; h = *host; dot = 0; + in_brackets = 0; for (i = 0; i < len; i++) { ch = h[i]; @@ -1665,11 +1666,27 @@ dot = 0; - if (ch == ':') { + if (ch == '[' && i == 0) { + /* start of literal IPv6 address */ + in_brackets = 1; + continue; + } + + /* + * Inside square brackets, the colon is a delimeter for an IPv6 address. + * Otherwise it comes before the port number, so remove it. + */ + if (ch == ':' && !in_brackets) { last = i; continue; } + if (ch == ']') { + /* end of literal IPv6 address */ + in_brackets = 0; + continue; + } + if (ngx_path_separator(ch) || ch == '\0') { return 0; } @@ -1679,6 +1696,11 @@ } } + if (in_brackets) { + /* missing the closing square bracket for IPv6 address */ + return 0; + } + if (dot) { last--; }