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--;
     }

Reply via email to