spaces in URI

Igor Sysoev igor at sysoev.ru
Fri Jun 11 12:09:20 MSD 2010


On Fri, Jun 11, 2010 at 02:54:35AM -0400, Peter Portante wrote:

> Hi Folks,
> 
> We are running into a small problem with bad HTTP clients.
> 
> We have sold a bunch of hardware with embedded HTTP clients which don't
> URL-encode the parameter values. For example:
> 
>   GET /a/r?did=X234 567 Y HTTP/1.1
> 
> We were using a pair of Apache servers behind a hardware load-balancer and
> switched our environment to front those Apache servers with a pair of Nginx
> servers. We actually use those Nginx servers for a number of other web sites
> we serve.
> 
> When we made this switch, these particular clients stopped working. Nginx is
> responding immediately after receiving the "GET" line above with "400 Bad
> Request". This *is* valid behavior on Nginx's part, as according to our
> understanding of the HTTP protocol, no spaces are allowed in the request
> URI.
> 
> Apache is apparently rather forgiving on this front. Is there some setting
> or configuration parameter in Nginx that would make it more forgiving of
> these spaces in the request URI?
> 
> If there is not, would it be difficult for us to modify Nginx to make it
> more forgiving? If so, any pointers as to where to start?
> 
> Our other options we can think of are:
> 
> 1. route HTTP traffic from these clients to Apache servers
> 2. leave them dead in the water until customers complain so we can tell them
>    to upgrade their firmware for the fix
> 
> Thanks for any help or pointers you can offer.

Try the attached patch against 0.8.40.


-- 
Igor Sysoev
http://sysoev.ru/en/
-------------- next part --------------
Index: src/http/ngx_http_parse.c
===================================================================
--- src/http/ngx_http_parse.c	(revision 2933)
+++ src/http/ngx_http_parse.c	(working copy)
@@ -112,8 +112,10 @@
         sw_schema_slash_slash,
         sw_host,
         sw_port,
+        sw_host_http_09,
         sw_after_slash_in_uri,
         sw_check_uri,
+        sw_check_uri_http_09,
         sw_uri,
         sw_http_09,
         sw_http_H,
@@ -357,7 +359,7 @@
                  */
                 r->uri_start = r->schema_end + 1;
                 r->uri_end = r->schema_end + 2;
-                state = sw_http_09;
+                state = sw_host_http_09;
                 break;
             default:
                 return NGX_HTTP_PARSE_INVALID_REQUEST;
@@ -383,13 +385,35 @@
                  */
                 r->uri_start = r->schema_end + 1;
                 r->uri_end = r->schema_end + 2;
-                state = sw_http_09;
+                state = sw_host_http_09;
                 break;
             default:
                 return NGX_HTTP_PARSE_INVALID_REQUEST;
             }
             break;
 
+        /* space+ after "http://host[:port] " */
+        case sw_host_http_09:
+            switch (ch) {
+            case ' ':
+                break;
+            case CR:
+                r->http_minor = 9;
+                state = sw_almost_done;
+                break;
+            case LF:
+                r->http_minor = 9;
+                goto done;
+            case 'H':
+                r->http_protocol.data = p;
+                state = sw_http_H;
+                break;
+            default:
+                return NGX_HTTP_PARSE_INVALID_REQUEST;
+            }
+            break;
+
+
         /* check "/.", "//", "%", and "\" (Win32) in URI */
         case sw_after_slash_in_uri:
 
@@ -401,7 +425,7 @@
             switch (ch) {
             case ' ':
                 r->uri_end = p;
-                state = sw_http_09;
+                state = sw_check_uri_http_09;
                 break;
             case CR:
                 r->uri_end = p;
@@ -466,7 +490,7 @@
                 break;
             case ' ':
                 r->uri_end = p;
-                state = sw_http_09;
+                state = sw_check_uri_http_09;
                 break;
             case CR:
                 r->uri_end = p;
@@ -503,6 +527,29 @@
             }
             break;
 
+        /* space+ after URI */
+        case sw_check_uri_http_09:
+            switch (ch) {
+            case ' ':
+                break;
+            case CR:
+                r->http_minor = 9;
+                state = sw_almost_done;
+                break;
+            case LF:
+                r->http_minor = 9;
+                goto done;
+            case 'H':
+                r->http_protocol.data = p;
+                state = sw_http_H;
+                break;
+            default:
+                state = sw_check_uri;
+                break;
+            }
+            break;
+
+
         /* URI */
         case sw_uri:
 
@@ -549,7 +596,8 @@
                 state = sw_http_H;
                 break;
             default:
-                return NGX_HTTP_PARSE_INVALID_REQUEST;
+                state = sw_uri;
+                break;
             }
             break;
 


More information about the nginx mailing list