Support multi-line folding in header values.

Normal value cb is called for subsequent lines.  LWS is skipped.
  Note that \t whitespace character is now supported after header field name.

  RFC 2616, Section 2.2
  "HTTP/1.1 header field values can be folded onto multiple lines if the
   continuation line begins with a space or horizontal tab. All linear
   white space, including folding, has the same semantics as SP. A
   recipient MAY replace any linear white space with a single SP before
   interpreting the field value or forwarding the message downstream."
v0.6
Sean Cunningham 14 years ago
parent 3258e4a455
commit b89f94414e

@ -241,6 +241,7 @@ enum state
, s_header_field
, s_header_value_start
, s_header_value
, s_header_value_lws
, s_header_almost_done
@ -1040,6 +1041,7 @@ size_t http_parser_execute (http_parser *parser,
}
case s_header_field_start:
header_field_start:
{
if (ch == CR) {
state = s_headers_almost_done;
@ -1217,7 +1219,7 @@ size_t http_parser_execute (http_parser *parser,
case s_header_value_start:
{
if (ch == ' ') break;
if (ch == ' ' || ch == '\t') break;
MARK(header_value);
@ -1360,7 +1362,7 @@ size_t http_parser_execute (http_parser *parser,
{
STRICT_CHECK(ch != LF);
state = s_header_field_start;
state = s_header_value_lws;
switch (header_state) {
case h_connection_keep_alive:
@ -1378,6 +1380,18 @@ size_t http_parser_execute (http_parser *parser,
break;
}
case s_header_value_lws:
{
if (ch == ' ' || ch == '\t')
state = s_header_value_start;
else
{
state = s_header_field_start;
goto header_field_start;
}
break;
}
case s_headers_almost_done:
headers_almost_done:
{

@ -582,6 +582,35 @@ const struct message requests[] =
,.body= ""
}
#define LINE_FOLDING_IN_HEADER 20
, {.name= "line folding in header value"
,.type= HTTP_REQUEST
,.raw= "GET / HTTP/1.1\r\n"
"Line1: abc\r\n"
"\tdef\r\n"
" ghi\r\n"
"\t\tjkl\r\n"
" mno \r\n"
"\t \tqrs\r\n"
"Line2: \t line2\t\r\n"
"\r\n"
,.should_keep_alive= TRUE
,.message_complete_on_eof= FALSE
,.http_major= 1
,.http_minor= 1
,.method= HTTP_GET
,.query_string= ""
,.fragment= ""
,.request_path= "/"
,.request_url= "/"
,.num_headers= 2
,.headers= { { "Line1", "abcdefghijklmno qrs" }
, { "Line2", "line2\t" }
}
,.body= ""
}
#define QUERY_TERMINATED_HOST 21
, {.name= "host terminated by a query string"
,.type= HTTP_REQUEST
@ -1943,7 +1972,7 @@ main (void)
"\tRA==\r\n"
"\t-----END CERTIFICATE-----\r\n"
"\r\n";
test_simple(dumbfuck2, 0);
test_simple(dumbfuck2, 1);
#if 0
// NOTE(Wed Nov 18 11:57:27 CET 2009) this seems okay. we just read body

Loading…
Cancel
Save