|
|
@ -280,6 +280,9 @@ enum state |
|
|
|
|
|
|
|
, s_header_field_start |
|
|
|
, s_header_field |
|
|
|
, s_header_value_discard_ws |
|
|
|
, s_header_value_discard_ws_almost_done |
|
|
|
, s_header_value_discard_lws |
|
|
|
, s_header_value_start |
|
|
|
, s_header_value |
|
|
|
, s_header_value_lws |
|
|
@ -1380,7 +1383,7 @@ size_t http_parser_execute (http_parser *parser, |
|
|
|
} |
|
|
|
|
|
|
|
if (ch == ':') { |
|
|
|
parser->state = s_header_value_start; |
|
|
|
parser->state = s_header_value_discard_ws; |
|
|
|
CALLBACK_DATA(header_field); |
|
|
|
break; |
|
|
|
} |
|
|
@ -1401,28 +1404,28 @@ size_t http_parser_execute (http_parser *parser, |
|
|
|
goto error; |
|
|
|
} |
|
|
|
|
|
|
|
case s_header_value_start: |
|
|
|
{ |
|
|
|
case s_header_value_discard_ws: |
|
|
|
if (ch == ' ' || ch == '\t') break; |
|
|
|
|
|
|
|
MARK(header_value); |
|
|
|
|
|
|
|
parser->state = s_header_value; |
|
|
|
parser->index = 0; |
|
|
|
|
|
|
|
if (ch == CR) { |
|
|
|
parser->header_state = h_general; |
|
|
|
parser->state = s_header_almost_done; |
|
|
|
CALLBACK_DATA(header_value); |
|
|
|
parser->state = s_header_value_discard_ws_almost_done; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
if (ch == LF) { |
|
|
|
parser->state = s_header_field_start; |
|
|
|
CALLBACK_DATA(header_value); |
|
|
|
parser->state = s_header_value_discard_lws; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
/* FALLTHROUGH */ |
|
|
|
|
|
|
|
case s_header_value_start: |
|
|
|
{ |
|
|
|
MARK(header_value); |
|
|
|
|
|
|
|
parser->state = s_header_value; |
|
|
|
parser->index = 0; |
|
|
|
|
|
|
|
c = LOWER(ch); |
|
|
|
|
|
|
|
switch (parser->header_state) { |
|
|
@ -1570,7 +1573,17 @@ size_t http_parser_execute (http_parser *parser, |
|
|
|
STRICT_CHECK(ch != LF); |
|
|
|
|
|
|
|
parser->state = s_header_value_lws; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
case s_header_value_lws: |
|
|
|
{ |
|
|
|
if (ch == ' ' || ch == '\t') { |
|
|
|
parser->state = s_header_value_start; |
|
|
|
goto reexecute_byte; |
|
|
|
} |
|
|
|
|
|
|
|
/* finished the header */ |
|
|
|
switch (parser->header_state) { |
|
|
|
case h_connection_keep_alive: |
|
|
|
parser->flags |= F_CONNECTION_KEEP_ALIVE; |
|
|
@ -1585,19 +1598,29 @@ size_t http_parser_execute (http_parser *parser, |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
parser->state = s_header_field_start; |
|
|
|
goto reexecute_byte; |
|
|
|
} |
|
|
|
|
|
|
|
case s_header_value_discard_ws_almost_done: |
|
|
|
{ |
|
|
|
STRICT_CHECK(ch != LF); |
|
|
|
parser->state = s_header_value_discard_lws; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
case s_header_value_lws: |
|
|
|
case s_header_value_discard_lws: |
|
|
|
{ |
|
|
|
if (ch == ' ' || ch == '\t') |
|
|
|
parser->state = s_header_value_start; |
|
|
|
else |
|
|
|
{ |
|
|
|
if (ch == ' ' || ch == '\t') { |
|
|
|
parser->state = s_header_value_discard_ws; |
|
|
|
break; |
|
|
|
} else { |
|
|
|
/* header value was empty */ |
|
|
|
MARK(header_value); |
|
|
|
parser->state = s_header_field_start; |
|
|
|
CALLBACK_DATA_NOADVANCE(header_value); |
|
|
|
goto reexecute_byte; |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
case s_headers_almost_done: |
|
|
|