Skip to content

Commit cf0b3dc

Browse files
committed
deps: sync deps/http_parser with nodejs/http_parser
The upstream and dep were slightly out of sync due to the way the recent security update had to be done. This brings the two back into sync. This update includes a couple of fixed tests and a performance related semver-patch update to the http method parsing. PR-URL: #5600 Reviewed-By: Fedor Indutny <[email protected]> Reviewed-By: Johan Bergström <[email protected]>
1 parent 89d5379 commit cf0b3dc

File tree

3 files changed

+45
-89
lines changed

3 files changed

+45
-89
lines changed

deps/http_parser/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
HTTP Parser
22
===========
33

4-
[![Build Status](https://travis-ci.org/joyent/http-parser.png?branch=master)](https://travis-ci.org/joyent/http-parser)
4+
[![Build Status](https://api.travis-ci.org/nodejs/http-parser.svg?branch=master)](https://travis-ci.org/nodejs/http-parser)
55

66
This is a parser for HTTP messages written in C. It parses both requests and
77
responses. The parser is designed to be used in performance HTTP

deps/http_parser/http_parser.c

+33-82
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ do { \
123123
FOR##_mark = NULL; \
124124
} \
125125
} while (0)
126-
126+
127127
/* Run the data callback FOR and consume the current byte */
128128
#define CALLBACK_DATA(FOR) \
129129
CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1)
@@ -646,7 +646,7 @@ size_t http_parser_execute (http_parser *parser,
646646
const char *status_mark = 0;
647647
enum state p_state = (enum state) parser->state;
648648
const unsigned int lenient = parser->lenient_http_headers;
649-
649+
650650
/* We're in an error state. Don't bother doing anything. */
651651
if (HTTP_PARSER_ERRNO(parser) != HPE_OK) {
652652
return 0;
@@ -1007,89 +1007,40 @@ size_t http_parser_execute (http_parser *parser,
10071007
UPDATE_STATE(s_req_spaces_before_url);
10081008
} else if (ch == matcher[parser->index]) {
10091009
; /* nada */
1010-
} else if (parser->method == HTTP_CONNECT) {
1011-
if (parser->index == 1 && ch == 'H') {
1012-
parser->method = HTTP_CHECKOUT;
1013-
} else if (parser->index == 2 && ch == 'P') {
1014-
parser->method = HTTP_COPY;
1015-
} else {
1016-
SET_ERRNO(HPE_INVALID_METHOD);
1017-
goto error;
1018-
}
1019-
} else if (parser->method == HTTP_MKCOL) {
1020-
if (parser->index == 1 && ch == 'O') {
1021-
parser->method = HTTP_MOVE;
1022-
} else if (parser->index == 1 && ch == 'E') {
1023-
parser->method = HTTP_MERGE;
1024-
} else if (parser->index == 1 && ch == '-') {
1025-
parser->method = HTTP_MSEARCH;
1026-
} else if (parser->index == 2 && ch == 'A') {
1027-
parser->method = HTTP_MKACTIVITY;
1028-
} else if (parser->index == 3 && ch == 'A') {
1029-
parser->method = HTTP_MKCALENDAR;
1030-
} else {
1031-
SET_ERRNO(HPE_INVALID_METHOD);
1032-
goto error;
1033-
}
1034-
} else if (parser->method == HTTP_SUBSCRIBE) {
1035-
if (parser->index == 1 && ch == 'E') {
1036-
parser->method = HTTP_SEARCH;
1037-
} else {
1038-
SET_ERRNO(HPE_INVALID_METHOD);
1039-
goto error;
1040-
}
1041-
} else if (parser->method == HTTP_REPORT) {
1042-
if (parser->index == 2 && ch == 'B') {
1043-
parser->method = HTTP_REBIND;
1044-
} else {
1045-
SET_ERRNO(HPE_INVALID_METHOD);
1046-
goto error;
1047-
}
1048-
} else if (parser->index == 1) {
1049-
if (parser->method == HTTP_POST) {
1050-
if (ch == 'R') {
1051-
parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */
1052-
} else if (ch == 'U') {
1053-
parser->method = HTTP_PUT; /* or HTTP_PURGE */
1054-
} else if (ch == 'A') {
1055-
parser->method = HTTP_PATCH;
1056-
} else {
1057-
SET_ERRNO(HPE_INVALID_METHOD);
1058-
goto error;
1059-
}
1060-
} else if (parser->method == HTTP_LOCK) {
1061-
if (ch == 'I') {
1062-
parser->method = HTTP_LINK;
1063-
} else {
1064-
SET_ERRNO(HPE_INVALID_METHOD);
1065-
goto error;
1066-
}
1067-
}
1068-
} else if (parser->index == 2) {
1069-
if (parser->method == HTTP_PUT) {
1070-
if (ch == 'R') {
1071-
parser->method = HTTP_PURGE;
1072-
} else {
1073-
SET_ERRNO(HPE_INVALID_METHOD);
1074-
goto error;
1075-
}
1076-
} else if (parser->method == HTTP_UNLOCK) {
1077-
if (ch == 'S') {
1078-
parser->method = HTTP_UNSUBSCRIBE;
1079-
} else if(ch == 'B') {
1080-
parser->method = HTTP_UNBIND;
1081-
} else {
1010+
} else if (IS_ALPHA(ch)) {
1011+
1012+
switch (parser->method << 16 | parser->index << 8 | ch) {
1013+
#define XX(meth, pos, ch, new_meth) \
1014+
case (HTTP_##meth << 16 | pos << 8 | ch): \
1015+
parser->method = HTTP_##new_meth; break;
1016+
1017+
XX(POST, 1, 'U', PUT)
1018+
XX(POST, 1, 'A', PATCH)
1019+
XX(CONNECT, 1, 'H', CHECKOUT)
1020+
XX(CONNECT, 2, 'P', COPY)
1021+
XX(MKCOL, 1, 'O', MOVE)
1022+
XX(MKCOL, 1, 'E', MERGE)
1023+
XX(MKCOL, 2, 'A', MKACTIVITY)
1024+
XX(MKCOL, 3, 'A', MKCALENDAR)
1025+
XX(SUBSCRIBE, 1, 'E', SEARCH)
1026+
XX(REPORT, 2, 'B', REBIND)
1027+
XX(POST, 1, 'R', PROPFIND)
1028+
XX(PROPFIND, 4, 'P', PROPPATCH)
1029+
XX(PUT, 2, 'R', PURGE)
1030+
XX(LOCK, 1, 'I', LINK)
1031+
XX(UNLOCK, 2, 'S', UNSUBSCRIBE)
1032+
XX(UNLOCK, 2, 'B', UNBIND)
1033+
XX(UNLOCK, 3, 'I', UNLINK)
1034+
#undef XX
1035+
1036+
default:
10821037
SET_ERRNO(HPE_INVALID_METHOD);
10831038
goto error;
1084-
}
1085-
} else {
1086-
SET_ERRNO(HPE_INVALID_METHOD);
1087-
goto error;
10881039
}
1089-
} else if (parser->index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') {
1090-
parser->method = HTTP_PROPPATCH;
1091-
} else if (parser->index == 3 && parser->method == HTTP_UNLOCK && ch == 'I') {
1092-
parser->method = HTTP_UNLINK;
1040+
} else if (ch == '-' &&
1041+
parser->index == 1 &&
1042+
parser->method == HTTP_MKCOL) {
1043+
parser->method = HTTP_MSEARCH;
10931044
} else {
10941045
SET_ERRNO(HPE_INVALID_METHOD);
10951046
goto error;

deps/http_parser/test.c

+11-6
Original file line numberDiff line numberDiff line change
@@ -2444,7 +2444,7 @@ upgrade_message_fix(char *body, const size_t nread, const size_t nmsgs, ...) {
24442444
va_list ap;
24452445
size_t i;
24462446
size_t off = 0;
2447-
2447+
24482448
va_start(ap, nmsgs);
24492449

24502450
for (i = 0; i < nmsgs; i++) {
@@ -3282,10 +3282,10 @@ test_invalid_header_content (int req, const char* str)
32823282
"HTTP/1.1 200 OK\r\n";
32833283
parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf));
32843284
assert(parsed == strlen(buf));
3285-
3285+
32863286
buf = str;
32873287
size_t buflen = strlen(buf);
3288-
3288+
32893289
parsed = http_parser_execute(&parser, &settings_null, buf, buflen);
32903290
if (parsed != buflen) {
32913291
assert(HTTP_PARSER_ERRNO(&parser) == HPE_INVALID_HEADER_TOKEN);
@@ -3316,10 +3316,10 @@ test_invalid_header_field (int req, const char* str)
33163316
"HTTP/1.1 200 OK\r\n";
33173317
parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf));
33183318
assert(parsed == strlen(buf));
3319-
3319+
33203320
buf = str;
33213321
size_t buflen = strlen(buf);
3322-
3322+
33233323
parsed = http_parser_execute(&parser, &settings_null, buf, buflen);
33243324
if (parsed != buflen) {
33253325
assert(HTTP_PARSER_ERRNO(&parser) == HPE_INVALID_HEADER_TOKEN);
@@ -3383,7 +3383,7 @@ test_chunked_content_length_error (int req)
33833383

33843384
parsed = http_parser_execute(&parser, &settings_null, buf, buflen);
33853385
if (parsed != buflen) {
3386-
assert(HTTP_PARSER_ERRNO(&parser) == HPE_CHUNKED_WITH_CONTENT_LENGTH);
3386+
assert(HTTP_PARSER_ERRNO(&parser) == HPE_UNEXPECTED_CONTENT_LENGTH);
33873387
return;
33883388
}
33893389

@@ -3933,6 +3933,11 @@ main (void)
39333933

39343934
test_simple("GET / HTP/1.1\r\n\r\n", HPE_INVALID_VERSION);
39353935

3936+
// Extended characters - see nodejs/test/parallel/test-http-headers-obstext.js
3937+
test_simple("GET / HTTP/1.1\r\n"
3938+
"Test: Düsseldorf\r\n",
3939+
HPE_OK);
3940+
39363941
// Well-formed but incomplete
39373942
test_simple("GET / HTTP/1.1\r\n"
39383943
"Content-Type: text/plain\r\n"

0 commit comments

Comments
 (0)