diff src/http/ngx_http_parse.c @ 58:b55cbf18157e NGINX_0_1_29

nginx 0.1.29 *) Feature: the ngx_http_ssi_module supports "include virtual" command. *) Feature: the ngx_http_ssi_module supports the condition command like 'if expr="$NAME"' and "else" and "endif" commands. Only one nested level is supported. *) Feature: the ngx_http_ssi_module supports the DATE_LOCAL and DATE_GMT variables and "config timefmt" command. *) Feature: the "ssi_ignore_recycled_buffers" directive. *) Bugfix: the "echo" command did not show the default value for the empty QUERY_STRING variable. *) Change: the ngx_http_proxy_module was rewritten. *) Feature: the "proxy_redirect", "proxy_pass_request_headers", "proxy_pass_request_body", and "proxy_method" directives. *) Feature: the "proxy_set_header" directive. The "proxy_x_var" was canceled and must be replaced with the proxy_set_header directive. *) Change: the "proxy_preserve_host" is canceled and must be replaced with the "proxy_set_header Host $host" and the "proxy_redirect off" directives, the "proxy_set_header Host $host:$proxy_port" directive and the appropriate proxy_redirect directives. *) Change: the "proxy_set_x_real_ip" is canceled and must be replaced with the "proxy_set_header X-Real-IP $remote_addr" directive. *) Change: the "proxy_add_x_forwarded_for" is canceled and must be replaced with the "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for" directive. *) Change: the "proxy_set_x_url" is canceled and must be replaced with the "proxy_set_header X-URL http://$host:$server_port$request_uri" directive. *) Feature: the "fastcgi_param" directive. *) Change: the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params" directive are canceled and must be replaced with the fastcgi_param directives. *) Feature: the "index" directive can use the variables. *) Feature: the "index" directive can be used at http and server levels. *) Change: the last index only in the "index" directive can be absolute. *) Feature: the "rewrite" directive can use the variables. *) Feature: the "internal" directive. *) Feature: the CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR, SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME, REQUEST_METHOD, REQUEST_URI, and REMOTE_USER variables. *) Change: nginx now passes the invalid lines in a client request headers or a backend response header. *) Bugfix: if the backend did not transfer response for a long time and the "send_timeout" was less than "proxy_read_timeout", then nginx returned the 408 response. *) Bugfix: the segmentation fault was occurred if the backend sent an invalid line in response header; bug appeared in 0.1.26. *) Bugfix: the segmentation fault may occurred in FastCGI fault tolerance configuration. *) Bugfix: the "expires" directive did not remove the previous "Expires" and "Cache-Control" headers. *) Bugfix: nginx did not take into account trailing dot in "Host" header line. *) Bugfix: the ngx_http_auth_module did not work under Linux. *) Bugfix: the rewrite directive worked incorrectly, if the arguments were in a request. *) Bugfix: nginx could not be built on MacOS X.
author Igor Sysoev <http://sysoev.ru>
date Thu, 12 May 2005 00:00:00 +0400
parents 3050baa54a26
children df7d3fff122b
line wrap: on
line diff
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -9,7 +9,8 @@
 #include <ngx_http.h>
 
 
-ngx_int_t ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
+ngx_int_t
+ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
 {
     u_char  c, ch, *p, *m;
     enum {
@@ -63,7 +64,7 @@ ngx_int_t ngx_http_parse_request_line(ng
 
         case sw_method:
             if (ch == ' ') {
-                r->method_end = p;
+                r->method_end = p - 1;
                 m = r->request_start;
 
                 if (p - m == 3) {
@@ -502,7 +503,8 @@ done:
 }
 
 
-ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b)
+ngx_int_t
+ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b)
 {
     u_char      c, ch, *p;
     ngx_uint_t  hash;
@@ -513,7 +515,6 @@ ngx_int_t ngx_http_parse_header_line(ngx
         sw_value,
         sw_space_after_value,
         sw_ignore_line,
-        sw_skip_line,
         sw_almost_done,
         sw_header_almost_done
     } state;
@@ -528,8 +529,6 @@ ngx_int_t ngx_http_parse_header_line(ngx
 
         /* first char */
         case sw_start:
-            r->invalid_header = 0;
-
             switch (ch) {
             case CR:
                 r->header_end = p;
@@ -548,18 +547,11 @@ ngx_int_t ngx_http_parse_header_line(ngx
                     break;
                 }
 
-                if (ch == '-') {
-                    hash = ch;
-                    break;
-                }
-
                 if (ch >= '0' && ch <= '9') {
                     hash = ch;
                     break;
                 }
 
-                r->invalid_header = 1;
-                state = sw_skip_line;
                 break;
 
             }
@@ -589,18 +581,31 @@ ngx_int_t ngx_http_parse_header_line(ngx
                 break;
             }
 
+            if (ch == CR) {
+                r->header_name_end = p;
+                r->header_start = p;
+                r->header_end = p;
+                state = sw_almost_done;
+                break;
+            }
+
+            if (ch == LF) {
+                r->header_name_end = p;
+                r->header_start = p;
+                r->header_end = p;
+                goto done;
+            }
+
             /* IIS may send the duplicate "HTTP/1.1 ..." lines */
             if (ch == '/'
-                && r->proxy
-                && p - r->header_start == 4
-                && ngx_strncmp(r->header_start, "HTTP", 4) == 0)
+                && r->upstream
+                && p - r->header_name_start == 4
+                && ngx_strncmp(r->header_name_start, "HTTP", 4) == 0)
             {
                 state = sw_ignore_line;
                 break;
             }
 
-            r->invalid_header = 1;
-            state = sw_skip_line;
             break;
 
         /* space* before header value */
@@ -609,11 +614,13 @@ ngx_int_t ngx_http_parse_header_line(ngx
             case ' ':
                 break;
             case CR:
-                r->header_start = r->header_end = p;
+                r->header_start = p;
+                r->header_end = p;
                 state = sw_almost_done;
                 break;
             case LF:
-                r->header_start = r->header_end = p;
+                r->header_start = p;
+                r->header_end = p;
                 goto done;
             default:
                 r->header_start = p;
@@ -666,21 +673,6 @@ ngx_int_t ngx_http_parse_header_line(ngx
             }
             break;
 
-        /* skip header line */
-        case sw_skip_line:
-            switch (ch) {
-            case CR:
-                r->header_end = p;
-                state = sw_almost_done;
-                break;
-            case LF:
-                r->header_end = p;
-                goto done;
-            default:
-                break;
-            }
-            break;
-
         /* end of header line */
         case sw_almost_done:
             switch (ch) {
@@ -724,7 +716,8 @@ header_done:
 }
 
 
-ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r)
+ngx_int_t
+ngx_http_parse_complex_uri(ngx_http_request_t *r)
 {
     u_char  c, ch, decoded, *p, *u;
     enum {
@@ -1001,3 +994,75 @@ done:
 
     return NGX_OK;
 }
+
+
+ngx_int_t
+ngx_http_parse_multi_header_lines(ngx_array_t *headers, ngx_str_t *name,
+    ngx_str_t *value)
+{
+    ngx_uint_t         i;
+    u_char            *start, *last, *end, ch;
+    ngx_table_elt_t  **h;
+
+    h = headers->elts;
+
+    for (i = 0; i < headers->nelts; i++) {
+
+        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, headers->pool->log, 0,
+                       "parse header: \"%V: %V\"", &h[i]->key, &h[i]->value);
+
+        if (name->len > h[i]->value.len) {
+            continue;
+        }
+    
+        start = h[i]->value.data;
+        end = h[i]->value.data + h[i]->value.len;
+
+        while (start < end) {
+
+            if (ngx_strncasecmp(start, name->data, name->len) != 0) {
+                goto skip;
+            }
+
+            for (start += name->len; start < end && *start == ' '; start++) {
+                /* void */
+            }
+
+            if (value == NULL) {
+                if (start == end || *start == ',') {
+                    return i;
+                }
+
+                goto skip;
+            }
+
+            if (start == end || *start++ != '=') {
+                /* the invalid header value */
+                goto skip;
+            }
+
+            while (start < end && *start == ' ') { start++; }
+
+            for (last = start; last < end && *last != ';'; last++) {
+                /* void */
+            }
+
+            value->len = last - start;
+            value->data = start;
+
+            return i;
+
+        skip:
+            while (start < end) {
+                ch = *start++;
+                if (ch == ';' || ch == ',') {
+                    break;
+                }
+            }
+
+            while (start < end && *start == ' ') { start++; }
+        }
+    }
+
+    return NGX_DECLINED;
+}