Fix response body is not read

With HTTP/1.1, if neither Content-Length nor Transfer-Encoding is present,
section 4.4 of RFC 2616 suggests http-parser needs to read a response body
until the connection is closed (except the response must not include a body)

See also joyent/node#2457.
Fixes #72
v0.6
koichik 13 years ago committed by Ryan Dahl
parent 3cf68f9a70
commit b47c44d7a6

@ -1733,9 +1733,20 @@ http_should_keep_alive (http_parser *parser)
/* HTTP/1.1 */ /* HTTP/1.1 */
if (parser->flags & F_CONNECTION_CLOSE) { if (parser->flags & F_CONNECTION_CLOSE) {
return 0; return 0;
} else {
return 1;
} }
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) {

@ -780,8 +780,8 @@ const struct message responses[] =
, {.name= "404 no headers no body" , {.name= "404 no headers no body"
,.type= HTTP_RESPONSE ,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 404 Not Found\r\n\r\n" ,.raw= "HTTP/1.1 404 Not Found\r\n\r\n"
,.should_keep_alive= TRUE ,.should_keep_alive= FALSE
,.message_complete_on_eof= FALSE ,.message_complete_on_eof= TRUE
,.http_major= 1 ,.http_major= 1
,.http_minor= 1 ,.http_minor= 1
,.status_code= 404 ,.status_code= 404
@ -795,8 +795,8 @@ const struct message responses[] =
, {.name= "301 no response phrase" , {.name= "301 no response phrase"
,.type= HTTP_RESPONSE ,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 301\r\n\r\n" ,.raw= "HTTP/1.1 301\r\n\r\n"
,.should_keep_alive = TRUE ,.should_keep_alive = FALSE
,.message_complete_on_eof= FALSE ,.message_complete_on_eof= TRUE
,.http_major= 1 ,.http_major= 1
,.http_minor= 1 ,.http_minor= 1
,.status_code= 301 ,.status_code= 301
@ -1057,8 +1057,46 @@ const struct message responses[] =
{} {}
,.body= "" ,.body= ""
} }
, {.name= NULL } /* sentinel */
#define NO_CONTENT_LENGTH_NO_TRANSFER_ENCODING_RESPONSE 13
/* The client should wait for the server's EOF. That is, when neither
* content-length nor transfer-encoding is specified, the end of body
* is specified by the EOF.
*/
, {.name= "neither content-length nor transfer-encoding response"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"\r\n"
"hello world"
,.should_keep_alive= FALSE
,.message_complete_on_eof= TRUE
,.http_major= 1
,.http_minor= 1
,.status_code= 200
,.num_headers= 1
,.headers=
{ { "Content-Type", "text/plain" }
}
,.body= "hello world"
}
#define NO_HEADERS_NO_BODY_204 14
, {.name= "204 no headers no body"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 204 No Content\r\n\r\n"
,.should_keep_alive= TRUE
,.message_complete_on_eof= FALSE
,.http_major= 1
,.http_minor= 1
,.status_code= 204
,.num_headers= 0
,.headers= {}
,.body_size= 0
,.body= ""
}
, {.name= NULL } /* sentinel */
}; };
int int
@ -1888,7 +1926,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_404] , &responses[NO_HEADERS_NO_BODY_204]
, &responses[NO_REASON_PHRASE] , &responses[NO_REASON_PHRASE]
); );

Loading…
Cancel
Save