Merge pull request #73 from pgriess/http-10-message-length

Get HTTP/1.1 message length logic working for HTTP/1.0
v0.10
Peter Griess 13 years ago
commit eb04bbe1fa

@ -389,6 +389,8 @@ static struct {
}; };
#undef HTTP_STRERROR_GEN #undef HTTP_STRERROR_GEN
int http_message_needs_eof(http_parser *parser);
/* Our URL parser. /* Our URL parser.
* *
* This is designed to be shared by http_parser_execute() for URL validation, * This is designed to be shared by http_parser_execute() for URL validation,
@ -1591,7 +1593,8 @@ size_t http_parser_execute (http_parser *parser,
/* Content-Length header given and non-zero */ /* Content-Length header given and non-zero */
parser->state = s_body_identity; parser->state = s_body_identity;
} else { } else {
if (parser->type == HTTP_REQUEST || http_should_keep_alive(parser)) { if (parser->type == HTTP_REQUEST ||
!http_message_needs_eof(parser)) {
/* Assume content-length 0 - read the next */ /* Assume content-length 0 - read the next */
parser->state = NEW_MESSAGE(); parser->state = NEW_MESSAGE();
CALLBACK_NOTIFY(message_complete); CALLBACK_NOTIFY(message_complete);
@ -1794,6 +1797,30 @@ error:
} }
/* Does the parser need to see an EOF to find the end of the message? */
int
http_message_needs_eof (http_parser *parser)
{
if (parser->type == HTTP_REQUEST) {
return 0;
}
/* See RFC 2616 section 4.4 */
if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */
parser->status_code == 204 || /* No Content */
parser->status_code == 304 || /* Not Modified */
parser->flags & F_SKIPBODY) { /* response to a HEAD request */
return 0;
}
if ((parser->flags & F_CHUNKED) || parser->content_length >= 0) {
return 0;
}
return 1;
}
int int
http_should_keep_alive (http_parser *parser) http_should_keep_alive (http_parser *parser)
{ {
@ -1802,27 +1829,14 @@ http_should_keep_alive (http_parser *parser)
if (parser->flags & F_CONNECTION_CLOSE) { if (parser->flags & F_CONNECTION_CLOSE) {
return 0; return 0;
} }
if (parser->type == HTTP_RESPONSE) {
/* See RFC 2616 section 4.4 */
if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */
parser->status_code == 204 || /* No Content */
parser->status_code == 304 || /* Not Modified */
parser->flags & F_SKIPBODY) { /* response to a HEAD request */
return 1;
}
if (!(parser->flags & F_CHUNKED) && parser->content_length == -1) {
return 0;
}
}
return 1;
} else { } else {
/* HTTP/1.0 or earlier */ /* HTTP/1.0 or earlier */
if (parser->flags & F_CONNECTION_KEEP_ALIVE) { if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) {
return 1;
} else {
return 0; return 0;
} }
} }
return !http_message_needs_eof(parser);
} }

107
test.c

@ -1142,23 +1142,118 @@ const struct message responses[] =
,.body= "hello world" ,.body= "hello world"
} }
#define NO_HEADERS_NO_BODY_204 13 #define NO_BODY_HTTP10_KA_200 13
, {.name= "204 no headers no body" , {.name= "HTTP/1.0 with keep-alive and EOF-terminated 200 status"
,.type= HTTP_RESPONSE ,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 204 No Content\r\n\r\n" ,.raw= "HTTP/1.0 200 OK\r\n"
"Connection: keep-alive\r\n"
"\r\n"
,.should_keep_alive= FALSE
,.message_complete_on_eof= TRUE
,.http_major= 1
,.http_minor= 0
,.status_code= 200
,.num_headers= 1
,.headers=
{ { "Connection", "keep-alive" }
}
,.body_size= 0
,.body= ""
}
#define NO_BODY_HTTP10_KA_204 14
, {.name= "HTTP/1.0 with keep-alive and a 204 status"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.0 204 No content\r\n"
"Connection: keep-alive\r\n"
"\r\n"
,.should_keep_alive= TRUE
,.message_complete_on_eof= FALSE
,.http_major= 1
,.http_minor= 0
,.status_code= 204
,.num_headers= 1
,.headers=
{ { "Connection", "keep-alive" }
}
,.body_size= 0
,.body= ""
}
#define NO_BODY_HTTP11_KA_200 15
, {.name= "HTTP/1.1 with an EOF-terminated 200 status"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 200 OK\r\n"
"\r\n"
,.should_keep_alive= FALSE
,.message_complete_on_eof= TRUE
,.http_major= 1
,.http_minor= 1
,.status_code= 200
,.num_headers= 0
,.headers={}
,.body_size= 0
,.body= ""
}
#define NO_BODY_HTTP11_KA_204 16
, {.name= "HTTP/1.1 with a 204 status"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 204 No content\r\n"
"\r\n"
,.should_keep_alive= TRUE ,.should_keep_alive= TRUE
,.message_complete_on_eof= FALSE ,.message_complete_on_eof= FALSE
,.http_major= 1 ,.http_major= 1
,.http_minor= 1 ,.http_minor= 1
,.status_code= 204 ,.status_code= 204
,.num_headers= 0 ,.num_headers= 0
,.headers= {} ,.headers={}
,.body_size= 0
,.body= ""
}
#define NO_BODY_HTTP11_NOKA_204 17
, {.name= "HTTP/1.1 with a 204 status and keep-alive disabled"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 204 No content\r\n"
"Connection: close\r\n"
"\r\n"
,.should_keep_alive= FALSE
,.message_complete_on_eof= FALSE
,.http_major= 1
,.http_minor= 1
,.status_code= 204
,.num_headers= 1
,.headers=
{ { "Connection", "close" }
}
,.body_size= 0
,.body= ""
}
#define NO_BODY_HTTP11_KA_CHUNKED_200 18
, {.name= "HTTP/1.1 with chunked endocing and a 200 response"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 200 OK\r\n"
"Transfer-Encoding: chunked\r\n"
"\r\n"
"0\r\n"
"\r\n"
,.should_keep_alive= TRUE
,.message_complete_on_eof= FALSE
,.http_major= 1
,.http_minor= 1
,.status_code= 200
,.num_headers= 1
,.headers=
{ { "Transfer-Encoding", "chunked" }
}
,.body_size= 0 ,.body_size= 0
,.body= "" ,.body= ""
} }
#if !HTTP_PARSER_STRICT #if !HTTP_PARSER_STRICT
#define SPACE_IN_FIELD_RES 14 #define SPACE_IN_FIELD_RES 19
/* Should handle spaces in header fields */ /* Should handle spaces in header fields */
, {.name= "field space" , {.name= "field space"
,.type= HTTP_RESPONSE ,.type= HTTP_RESPONSE
@ -2264,7 +2359,7 @@ main (void)
printf("response scan 1/2 "); printf("response scan 1/2 ");
test_scan( &responses[TRAILING_SPACE_ON_CHUNKED_BODY] test_scan( &responses[TRAILING_SPACE_ON_CHUNKED_BODY]
, &responses[NO_HEADERS_NO_BODY_204] , &responses[NO_BODY_HTTP10_KA_204]
, &responses[NO_REASON_PHRASE] , &responses[NO_REASON_PHRASE]
); );

Loading…
Cancel
Save