Skip to content
This repository was archived by the owner on Nov 6, 2022. It is now read-only.

Commit 068f054

Browse files
committed
Always skip body for 1xx, 204, and 304 responses
Fixes: #251
1 parent 28f3c35 commit 068f054

File tree

2 files changed

+22
-34
lines changed

2 files changed

+22
-34
lines changed

http_parser.c

+20-28
Original file line numberDiff line numberDiff line change
@@ -474,8 +474,6 @@ static struct {
474474
};
475475
#undef HTTP_STRERROR_GEN
476476

477-
int http_message_needs_eof(const http_parser *parser);
478-
479477
/* Our URL parser.
480478
*
481479
* This is designed to be shared by http_parser_execute() for URL validation,
@@ -887,6 +885,12 @@ size_t http_parser_execute (http_parser *parser,
887885

888886
case s_res_status_start:
889887
{
888+
/* See RFC 7230 section 3.3.3, step 1 */
889+
if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */
890+
parser->status_code == 204 || /* No Content */
891+
parser->status_code == 304) { /* Not Modified */
892+
parser->flags |= F_SKIPBODY;
893+
}
890894
MARK(status);
891895
UPDATE_STATE(s_res_status);
892896
parser->index = 0;
@@ -1856,7 +1860,7 @@ size_t http_parser_execute (http_parser *parser,
18561860
/* Content-Length header given and non-zero */
18571861
UPDATE_STATE(s_body_identity);
18581862
} else {
1859-
if (!http_message_needs_eof(parser)) {
1863+
if (parser->type == HTTP_REQUEST) {
18601864
/* Assume content-length 0 - read the next */
18611865
UPDATE_STATE(NEW_MESSAGE());
18621866
CALLBACK_NOTIFY(message_complete);
@@ -2084,30 +2088,6 @@ size_t http_parser_execute (http_parser *parser,
20842088
}
20852089

20862090

2087-
/* Does the parser need to see an EOF to find the end of the message? */
2088-
int
2089-
http_message_needs_eof (const http_parser *parser)
2090-
{
2091-
if (parser->type == HTTP_REQUEST) {
2092-
return 0;
2093-
}
2094-
2095-
/* See RFC 2616 section 4.4 */
2096-
if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */
2097-
parser->status_code == 204 || /* No Content */
2098-
parser->status_code == 304 || /* Not Modified */
2099-
parser->flags & F_SKIPBODY) { /* response to a HEAD request */
2100-
return 0;
2101-
}
2102-
2103-
if ((parser->flags & F_CHUNKED) || parser->content_length != ULLONG_MAX) {
2104-
return 0;
2105-
}
2106-
2107-
return 1;
2108-
}
2109-
2110-
21112091
int
21122092
http_should_keep_alive (const http_parser *parser)
21132093
{
@@ -2123,7 +2103,19 @@ http_should_keep_alive (const http_parser *parser)
21232103
}
21242104
}
21252105

2126-
return !http_message_needs_eof(parser);
2106+
/* RFC 7230 section 3.3.3, step 7:
2107+
* ... this is a response message without a declared message body length, so
2108+
* the message body length is determined by the number of octets received
2109+
* prior to the server closing the connection.
2110+
*/
2111+
if (parser->type == HTTP_RESPONSE &&
2112+
!(parser->flags & F_SKIPBODY) &&
2113+
!(parser->flags & F_CHUNKED) &&
2114+
parser->content_length == ULLONG_MAX) {
2115+
return 0;
2116+
}
2117+
2118+
return 1;
21272119
}
21282120

21292121

test.c

+2-6
Original file line numberDiff line numberDiff line change
@@ -1848,8 +1848,7 @@ const struct message responses[] =
18481848
,.http_minor= 1
18491849
,.status_code= 101
18501850
,.response_status= "Switching Protocols"
1851-
,.body= "body"
1852-
,.upgrade= "proto"
1851+
,.upgrade= "bodyproto"
18531852
,.num_headers= 3
18541853
,.headers=
18551854
{ { "Connection", "upgrade" }
@@ -1879,16 +1878,13 @@ const struct message responses[] =
18791878
,.http_minor= 1
18801879
,.status_code= 101
18811880
,.response_status= "Switching Protocols"
1882-
,.body= "body"
1883-
,.upgrade= "proto"
1881+
,.upgrade= "2\r\nbo\r\n2\r\ndy\r\n0\r\n\r\nproto"
18841882
,.num_headers= 3
18851883
,.headers=
18861884
{ { "Connection", "upgrade" }
18871885
, { "Upgrade", "h2c" }
18881886
, { "Transfer-Encoding", "chunked" }
18891887
}
1890-
,.num_chunks_complete= 3
1891-
,.chunk_lengths= { 2, 2 }
18921888
}
18931889

18941890
#define HTTP_200_RESPONSE_WITH_UPGRADE_HEADER 25

0 commit comments

Comments
 (0)