Multi-line headers patch

algorist nginx-forum at nginx.us
Thu Aug 27 00:36:28 MSD 2009


Ok, not sure if this work is for naught... Here is the patch file (whitespace is dropped by the form):

--- nginx-0.7.61-clean/src/http/ngx_http_parse.c	2009-04-23 16:38:59.000000000 +0000
+++ nginx-0.7.61/src/http/ngx_http_parse.c	2009-08-12 18:50:47.000000000 +0000
@@ -699,6 +699,14 @@
 }
 
 
+/* helper method that looks ahead one character to determine if the header is multiline */
+u_char
+next_char_indicates_multiline_header(u_char *p, ngx_buf_t *b) {
+    u_char next_char = ((p+1) < b->last ? *(p+1) : 0);
+    return (next_char && (next_char == ' ' || next_char == '\t'));
+}
+
+
 ngx_int_t
 ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b,
     ngx_uint_t allow_underscores)
@@ -712,6 +720,7 @@
         sw_value,
         sw_space_after_value,
         sw_ignore_line,
+        sw_almost_done_or_multiline_header,
         sw_almost_done,
         sw_header_almost_done
     } state;
@@ -858,11 +867,13 @@
                 break;
             case CR:
                 r->header_end = p;
-                state = sw_almost_done;
+                state = sw_almost_done_or_multiline_header;
                 break;
             case LF:
-                r->header_end = p;
-                goto done;
+                if (!next_char_indicates_multiline_header(p, b)) {
+                    r->header_end = p;
+                    goto done;
+                }
             }
             break;
 
@@ -872,10 +883,15 @@
             case ' ':
                 break;
             case CR:
-                state = sw_almost_done;
+              state = sw_almost_done_or_multiline_header;
                 break;
             case LF:
-                goto done;
+                if (next_char_indicates_multiline_header(p, b)) {
+                    state = sw_value;
+                } else {
+                    goto done;
+                }
+                break;
             default:
                 state = sw_value;
                 break;
@@ -893,6 +909,25 @@
             }
             break;
 
+        /* determine whether this is actually the end of the header or a multi-line header */
+        case sw_almost_done_or_multiline_header:
+          switch(ch) {
+          case LF:
+              if (next_char_indicates_multiline_header(p, b)) {
+                  state = sw_value;
+              } else {
+                  /* not a multi-line header, so rewind the current character and enter sw_almost_done state */
+                  p--;
+                  state = sw_almost_done;
+              }
+              break;
+          default:
+              /* not a multi-line header, so rewind the current character and enter sw_almost_done state */
+              p--;
+              state = sw_almost_done;
+          }
+          break;
+
         /* end of header line */
         case sw_almost_done:
             switch (ch) {

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,4903,5210#msg-5210






More information about the nginx mailing list