Skip to content

Commit 2fca40e

Browse files
committed
Upgrade http-parser
1 parent e97a481 commit 2fca40e

4 files changed

Lines changed: 43 additions & 15 deletions

File tree

deps/http_parser/http_parser.c

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737

3838
#define CALLBACK2(FOR) \
3939
do { \
40-
if (settings.on_##FOR) { \
41-
if (0 != settings.on_##FOR(parser)) return (p - data); \
40+
if (settings->on_##FOR) { \
41+
if (0 != settings->on_##FOR(parser)) return (p - data); \
4242
} \
4343
} while (0)
4444

@@ -55,8 +55,8 @@ do { \
5555
if (parser->FOR##_mark) { \
5656
parser->FOR##_size += p - parser->FOR##_mark; \
5757
if (parser->FOR##_size > MAX_FIELD_SIZE) return (p - data); \
58-
if (settings.on_##FOR) { \
59-
if (0 != settings.on_##FOR(parser, \
58+
if (settings->on_##FOR) { \
59+
if (0 != settings->on_##FOR(parser, \
6060
parser->FOR##_mark, \
6161
p - parser->FOR##_mark)) \
6262
{ \
@@ -232,6 +232,7 @@ enum flags
232232
, F_CONNECTION_CLOSE = 1 << 2
233233
, F_TRAILING = 1 << 3
234234
, F_UPGRADE = 1 << 4
235+
, F_SKIPBODY = 1 << 5
235236
};
236237

237238

@@ -282,7 +283,7 @@ enum flags
282283

283284

284285
size_t http_parser_execute (http_parser *parser,
285-
http_parser_settings settings,
286+
const http_parser_settings *settings,
286287
const char *data,
287288
size_t len)
288289
{
@@ -1327,15 +1328,36 @@ size_t http_parser_execute (http_parser *parser,
13271328

13281329
if (parser->flags & F_UPGRADE) parser->upgrade = 1;
13291330

1330-
CALLBACK2(headers_complete);
1331+
/* Here we call the headers_complete callback. This is somewhat
1332+
* different than other callbacks because if the user returns 1, we
1333+
* will interpret that as saying that this message has no body. This
1334+
* is needed for the annoying case of recieving a response to a HEAD
1335+
* request.
1336+
*/
1337+
if (settings->on_headers_complete) {
1338+
switch (settings->on_headers_complete(parser)) {
1339+
case 0:
1340+
break;
1341+
1342+
case 1:
1343+
parser->flags |= F_SKIPBODY;
1344+
break;
1345+
1346+
default:
1347+
return p - data; /* Error */
1348+
}
1349+
}
13311350

13321351
// Exit, the rest of the connect is in a different protocol.
13331352
if (parser->flags & F_UPGRADE) {
13341353
CALLBACK2(message_complete);
13351354
return (p - data);
13361355
}
13371356

1338-
if (parser->flags & F_CHUNKED) {
1357+
if (parser->flags & F_SKIPBODY) {
1358+
CALLBACK2(message_complete);
1359+
state = NEW_MESSAGE();
1360+
} else if (parser->flags & F_CHUNKED) {
13391361
/* chunked encoding - ignore Content-Length header */
13401362
state = s_chunk_size_start;
13411363
} else {
@@ -1364,7 +1386,7 @@ size_t http_parser_execute (http_parser *parser,
13641386
case s_body_identity:
13651387
to_read = MIN(pe - p, (ssize_t)(parser->content_length - parser->body_read));
13661388
if (to_read > 0) {
1367-
if (settings.on_body) settings.on_body(parser, p, to_read);
1389+
if (settings->on_body) settings->on_body(parser, p, to_read);
13681390
p += to_read - 1;
13691391
parser->body_read += to_read;
13701392
if (parser->body_read == parser->content_length) {
@@ -1378,7 +1400,7 @@ size_t http_parser_execute (http_parser *parser,
13781400
case s_body_identity_eof:
13791401
to_read = pe - p;
13801402
if (to_read > 0) {
1381-
if (settings.on_body) settings.on_body(parser, p, to_read);
1403+
if (settings->on_body) settings->on_body(parser, p, to_read);
13821404
p += to_read - 1;
13831405
parser->body_read += to_read;
13841406
}
@@ -1451,7 +1473,7 @@ size_t http_parser_execute (http_parser *parser,
14511473
to_read = MIN(pe - p, (ssize_t)(parser->content_length));
14521474

14531475
if (to_read > 0) {
1454-
if (settings.on_body) settings.on_body(parser, p, to_read);
1476+
if (settings->on_body) settings->on_body(parser, p, to_read);
14551477
p += to_read - 1;
14561478
}
14571479

deps/http_parser/http_parser.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ typedef struct http_parser_settings http_parser_settings;
4949
/* Callbacks should return non-zero to indicate an error. The parser will
5050
* then halt execution.
5151
*
52+
* The one exception is on_headers_complete. In a HTTP_RESPONSE parser
53+
* returning '1' from on_headers_complete will tell the parser that it
54+
* should not expect a body. This is used when receiving a response to a
55+
* HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
56+
* chunked' headers that indicate the presence of a body.
57+
*
5258
* http_data_cb does not return data chunks. It will be call arbitrarally
5359
* many times for each string. E.G. you might get 10 callbacks for "on_path"
5460
* each providing just a few characters more data.
@@ -149,7 +155,7 @@ void http_parser_init(http_parser *parser, enum http_parser_type type);
149155

150156

151157
size_t http_parser_execute(http_parser *parser,
152-
http_parser_settings settings,
158+
const http_parser_settings *settings,
153159
const char *data,
154160
size_t len);
155161

deps/http_parser/test.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -898,15 +898,15 @@ inline size_t parse (const char *buf, size_t len)
898898
{
899899
size_t nparsed;
900900
currently_parsing_eof = (len == 0);
901-
nparsed = http_parser_execute(parser, settings, buf, len);
901+
nparsed = http_parser_execute(parser, &settings, buf, len);
902902
return nparsed;
903903
}
904904

905905
inline size_t parse_count_body (const char *buf, size_t len)
906906
{
907907
size_t nparsed;
908908
currently_parsing_eof = (len == 0);
909-
nparsed = http_parser_execute(parser, settings_count_body, buf, len);
909+
nparsed = http_parser_execute(parser, &settings_count_body, buf, len);
910910
return nparsed;
911911
}
912912

src/node_http_parser.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ class Parser : public ObjectWrap {
245245
parser->got_exception_ = false;
246246

247247
size_t nparsed =
248-
http_parser_execute(&parser->parser_, settings, buffer->data()+off, len);
248+
http_parser_execute(&parser->parser_, &settings, buffer->data()+off, len);
249249

250250
// Unassign the 'buffer_' variable
251251
assert(parser->buffer_);
@@ -275,7 +275,7 @@ class Parser : public ObjectWrap {
275275
assert(!parser->buffer_);
276276
parser->got_exception_ = false;
277277

278-
http_parser_execute(&(parser->parser_), settings, NULL, 0);
278+
http_parser_execute(&(parser->parser_), &settings, NULL, 0);
279279

280280
if (parser->got_exception_) return Local<Value>();
281281

0 commit comments

Comments
 (0)