diff --git a/deps/http_parser/http_parser.c b/deps/http_parser/http_parser.c index bbeceb0a51..5e135f7b20 100644 --- a/deps/http_parser/http_parser.c +++ b/deps/http_parser/http_parser.c @@ -1733,9 +1733,20 @@ http_should_keep_alive (http_parser *parser) /* HTTP/1.1 */ if (parser->flags & F_CONNECTION_CLOSE) { 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 { /* HTTP/1.0 or earlier */ if (parser->flags & F_CONNECTION_KEEP_ALIVE) { diff --git a/deps/http_parser/http_parser.h b/deps/http_parser/http_parser.h index 76a61f26b7..69f66d6d22 100644 --- a/deps/http_parser/http_parser.h +++ b/deps/http_parser/http_parser.h @@ -28,7 +28,7 @@ extern "C" { #define HTTP_PARSER_VERSION_MINOR 0 #include -#if defined(_WIN32) && !defined(__MINGW32__) && !defined(_MSC_VER) +#if defined(_WIN32) && !defined(__MINGW32__) && (!defined(_MSC_VER) || _MSC_VER<1600) typedef __int8 int8_t; typedef unsigned __int8 uint8_t; typedef __int16 int16_t; diff --git a/deps/http_parser/test.c b/deps/http_parser/test.c index 6af0e787e9..be633eb3b8 100644 --- a/deps/http_parser/test.c +++ b/deps/http_parser/test.c @@ -780,8 +780,8 @@ const struct message responses[] = , {.name= "404 no headers no body" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 404 Not Found\r\n\r\n" - ,.should_keep_alive= TRUE - ,.message_complete_on_eof= FALSE + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= TRUE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 404 @@ -795,8 +795,8 @@ const struct message responses[] = , {.name= "301 no response phrase" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 301\r\n\r\n" - ,.should_keep_alive = TRUE - ,.message_complete_on_eof= FALSE + ,.should_keep_alive = FALSE + ,.message_complete_on_eof= TRUE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 301 @@ -1057,8 +1057,46 @@ const struct message responses[] = {} ,.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 @@ -1888,7 +1926,7 @@ main (void) printf("response scan 1/2 "); test_scan( &responses[TRAILING_SPACE_ON_CHUNKED_BODY] - , &responses[NO_HEADERS_NO_BODY_404] + , &responses[NO_HEADERS_NO_BODY_204] , &responses[NO_REASON_PHRASE] );