add http_should_keep_alive()

event_stream
Ryan Dahl 15 years ago
parent 5b37977e32
commit 5b00b6a64f

@ -146,7 +146,9 @@ static const uint32_t usual[] = {
}; };
enum state enum state
{ s_start_res = 1 /* important that this is > 0 */ { s_dead = 1 /* important that this is > 0 */
, s_start_res
, s_res_H , s_res_H
, s_res_HT , s_res_HT
, s_res_HTT , s_res_HTT
@ -289,6 +291,12 @@ size_t parse (http_parser *parser, const char *data, size_t len, int start_state
ch = *p; ch = *p;
switch (state) { switch (state) {
case s_dead:
/* this state is used after a 'Connection: close' message
* the parser will error out if it reads another message
*/
return 0;
case s_start_res: case s_start_res:
{ {
parser->flags = 0; parser->flags = 0;
@ -1241,7 +1249,7 @@ size_t parse (http_parser *parser, const char *data, size_t len, int start_state
if (parser->flags & F_TRAILING) { if (parser->flags & F_TRAILING) {
/* End of a chunked request */ /* End of a chunked request */
CALLBACK2(message_complete); CALLBACK2(message_complete);
state = start_state; state = http_should_keep_alive(parser) ? start_state : s_dead;
break; break;
} }
@ -1256,32 +1264,18 @@ size_t parse (http_parser *parser, const char *data, size_t len, int start_state
if (parser->content_length == 0) { if (parser->content_length == 0) {
/* Content-Length header given but zero: Content-Length: 0\r\n */ /* Content-Length header given but zero: Content-Length: 0\r\n */
CALLBACK2(message_complete); CALLBACK2(message_complete);
state = start_state; state = http_should_keep_alive(parser) ? start_state : s_dead;
} else if (parser->content_length > 0) { } else if (parser->content_length > 0) {
/* Content-Length header given and non-zero */ /* Content-Length header given and non-zero */
state = s_body_identity; state = s_body_identity;
} else { } else {
/* No Content-Length header, not chunked */ if (http_should_keep_alive(parser)) {
if (parser->http_major > 0 && parser->http_minor > 0) { /* Assume content-length 0 - read the next */
/* HTTP/1.0 or HTTP/1.1 */ CALLBACK2(message_complete);
if (parser->flags & F_CONNECTION_CLOSE) { state = start_state;
/* Read body until EOF */
state = s_body_identity_eof;
} else {
/* Message is done - read the next */
CALLBACK2(message_complete);
state = start_state;
}
} else { } else {
/* HTTP/1.0 or earlier */ /* Read body until EOF */
if (parser->flags & F_CONNECTION_KEEP_ALIVE) { state = s_body_identity_eof;
/* Message is done - read the next */
CALLBACK2(message_complete);
state = start_state;
} else {
/* Read body until EOF */
state = s_body_identity_eof;
}
} }
} }
} }
@ -1297,7 +1291,7 @@ size_t parse (http_parser *parser, const char *data, size_t len, int start_state
parser->body_read += to_read; parser->body_read += to_read;
if (parser->body_read == parser->content_length) { if (parser->body_read == parser->content_length) {
CALLBACK2(message_complete); CALLBACK2(message_complete);
state = start_state; state = http_should_keep_alive(parser) ? start_state : s_dead;
} }
} }
break; break;
@ -1440,6 +1434,27 @@ http_parse_responses (http_parser *parser, const char *data, size_t len)
} }
int
http_should_keep_alive (http_parser *parser)
{
if (parser->http_major > 0 && parser->http_minor > 0) {
/* HTTP/1.1 */
if (parser->flags & F_CONNECTION_CLOSE) {
return 0;
} else {
return 1;
}
} else {
/* HTTP/1.0 or earlier */
if (parser->flags & F_CONNECTION_KEEP_ALIVE) {
return 1;
} else {
return 0;
}
}
}
void void
http_parser_init (http_parser *parser) http_parser_init (http_parser *parser)
{ {

@ -112,6 +112,12 @@ struct http_parser {
void http_parser_init(http_parser *parser); void http_parser_init(http_parser *parser);
size_t http_parse_requests(http_parser *parser, const char *data, size_t len); size_t http_parse_requests(http_parser *parser, const char *data, size_t len);
size_t http_parse_responses(http_parser *parser, const char *data, size_t len); size_t http_parse_responses(http_parser *parser, const char *data, size_t len);
/* Call this in the on_headers_complete or on_message_complete callback to
* determine if this will be the last message on the connection.
* If you are the server, respond with the "Connection: close" header
* if you are the client, close the connection.
*/
int http_should_keep_alive(http_parser *parser);
#ifdef __cplusplus #ifdef __cplusplus
} }

@ -1085,9 +1085,9 @@ main (void)
); );
printf("request scan 2/3 "); printf("request scan 2/3 ");
test_scan( &requests[GET_FUNKY_CONTENT_LENGTH] test_scan( &requests[POST_CHUNKED_ALL_YOUR_BASE]
, &requests[POST_IDENTITY_BODY_WORLD] , &requests[POST_IDENTITY_BODY_WORLD]
, &requests[POST_CHUNKED_ALL_YOUR_BASE] , &requests[GET_FUNKY_CONTENT_LENGTH]
); );
printf("request scan 3/3 "); printf("request scan 3/3 ");

Loading…
Cancel
Save