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

Commit 227a6cb

Browse files
committed
Always skip body for 1xx, 204, and 304 responses
Fixes: #251
1 parent 0d0a24e commit 227a6cb

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;
@@ -1859,7 +1863,7 @@ size_t http_parser_execute (http_parser *parser,
18591863
/* Content-Length header given and non-zero */
18601864
UPDATE_STATE(s_body_identity);
18611865
} else {
1862-
if (!http_message_needs_eof(parser)) {
1866+
if (parser->type == HTTP_REQUEST) {
18631867
/* Assume content-length 0 - read the next */
18641868
UPDATE_STATE(NEW_MESSAGE());
18651869
CALLBACK_NOTIFY(message_complete);
@@ -2087,30 +2091,6 @@ size_t http_parser_execute (http_parser *parser,
20872091
}
20882092

20892093

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

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

21322124

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)