summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Lau <rlau@redhat.com>2020-11-26 15:26:15 +0000
committerRichard Lau <rlau@redhat.com>2020-12-23 14:15:01 +0000
commit323a6f114a93a534da70f61dd5a1f5e600c11406 (patch)
tree3138b6b2e0279ac45d304e3511aa7595c4beb5e3
parent357e2857c8385c303782ced2ac8b568df06d4326 (diff)
downloadnode-new-323a6f114a93a534da70f61dd5a1f5e600c11406.tar.gz
deps: update http-parser to http-parser@ec8b5ee63f
PR-URL: https://github.com/nodejs-private/node-private/pull/235 Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
-rw-r--r--deps/http_parser/Makefile2
-rw-r--r--deps/http_parser/README.md3
-rw-r--r--deps/http_parser/fuzzers/fuzz_parser.c26
-rw-r--r--deps/http_parser/fuzzers/fuzz_url.c14
-rw-r--r--deps/http_parser/http_parser.c26
-rw-r--r--deps/http_parser/http_parser.h23
-rw-r--r--deps/http_parser/test.c156
7 files changed, 220 insertions, 30 deletions
diff --git a/deps/http_parser/Makefile b/deps/http_parser/Makefile
index 9e8c1f0371..5d21221504 100644
--- a/deps/http_parser/Makefile
+++ b/deps/http_parser/Makefile
@@ -24,7 +24,7 @@ BINEXT ?=
SOLIBNAME = libhttp_parser
SOMAJOR = 2
SOMINOR = 9
-SOREV = 3
+SOREV = 4
ifeq (darwin,$(PLATFORM))
SOEXT ?= dylib
SONAME ?= $(SOLIBNAME).$(SOMAJOR).$(SOMINOR).$(SOEXT)
diff --git a/deps/http_parser/README.md b/deps/http_parser/README.md
index b265d71715..e38d3a5788 100644
--- a/deps/http_parser/README.md
+++ b/deps/http_parser/README.md
@@ -1,6 +1,9 @@
HTTP Parser
===========
+http-parser is [**not** actively maintained](https://github.com/nodejs/http-parser/issues/522).
+New projects and projects looking to migrate should consider [llhttp](https://github.com/nodejs/llhttp).
+
[![Build Status](https://api.travis-ci.org/nodejs/http-parser.svg?branch=master)](https://travis-ci.org/nodejs/http-parser)
This is a parser for HTTP messages written in C. It parses both requests and
diff --git a/deps/http_parser/fuzzers/fuzz_parser.c b/deps/http_parser/fuzzers/fuzz_parser.c
new file mode 100644
index 0000000000..1a8442c9b6
--- /dev/null
+++ b/deps/http_parser/fuzzers/fuzz_parser.c
@@ -0,0 +1,26 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include "http_parser.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+ static const http_parser_settings settings_null = {
+ .on_message_begin = 0
+ , .on_header_field = 0
+ ,.on_header_value = 0
+ ,.on_url = 0
+ ,.on_status = 0
+ ,.on_body = 0
+ ,.on_headers_complete = 0
+ ,.on_message_complete = 0
+ ,.on_chunk_header = 0
+ ,.on_chunk_complete = 0
+ };
+
+ http_parser parser;
+ http_parser_init(&parser, HTTP_BOTH);
+ http_parser_execute(&parser, &settings_null, (char*)data, size);
+
+ return 0;
+}
diff --git a/deps/http_parser/fuzzers/fuzz_url.c b/deps/http_parser/fuzzers/fuzz_url.c
new file mode 100644
index 0000000000..eca11a2edc
--- /dev/null
+++ b/deps/http_parser/fuzzers/fuzz_url.c
@@ -0,0 +1,14 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include "http_parser.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+ struct http_parser_url u;
+ http_parser_url_init(&u);
+ http_parser_parse_url((char*)data, size, 0, &u);
+ http_parser_parse_url((char*)data, size, 1, &u);
+
+ return 0;
+}
diff --git a/deps/http_parser/http_parser.c b/deps/http_parser/http_parser.c
index 0f76b6aca8..9be003e732 100644
--- a/deps/http_parser/http_parser.c
+++ b/deps/http_parser/http_parser.c
@@ -653,6 +653,8 @@ size_t http_parser_execute (http_parser *parser,
const char *status_mark = 0;
enum state p_state = (enum state) parser->state;
const unsigned int lenient = parser->lenient_http_headers;
+ const unsigned int allow_chunked_length = parser->allow_chunked_length;
+
uint32_t nread = parser->nread;
/* We're in an error state. Don't bother doing anything. */
@@ -731,6 +733,7 @@ reexecute:
if (ch == CR || ch == LF)
break;
parser->flags = 0;
+ parser->uses_transfer_encoding = 0;
parser->content_length = ULLONG_MAX;
if (ch == 'H') {
@@ -768,6 +771,7 @@ reexecute:
if (ch == CR || ch == LF)
break;
parser->flags = 0;
+ parser->uses_transfer_encoding = 0;
parser->content_length = ULLONG_MAX;
if (ch == 'H') {
@@ -925,6 +929,7 @@ reexecute:
if (ch == CR || ch == LF)
break;
parser->flags = 0;
+ parser->uses_transfer_encoding = 0;
parser->content_length = ULLONG_MAX;
if (UNLIKELY(!IS_ALPHA(ch))) {
@@ -1338,7 +1343,7 @@ reexecute:
parser->header_state = h_general;
} else if (parser->index == sizeof(TRANSFER_ENCODING)-2) {
parser->header_state = h_transfer_encoding;
- parser->flags |= F_TRANSFER_ENCODING;
+ parser->uses_transfer_encoding = 1;
}
break;
@@ -1798,14 +1803,19 @@ reexecute:
REEXECUTE();
}
- /* Cannot us transfer-encoding and a content-length header together
+ /* Cannot use transfer-encoding and a content-length header together
per the HTTP specification. (RFC 7230 Section 3.3.3) */
- if ((parser->flags & F_TRANSFER_ENCODING) &&
+ if ((parser->uses_transfer_encoding == 1) &&
(parser->flags & F_CONTENTLENGTH)) {
/* Allow it for lenient parsing as long as `Transfer-Encoding` is
- * not `chunked`
+ * not `chunked` or allow_length_with_encoding is set
*/
- if (!lenient || (parser->flags & F_CHUNKED)) {
+ if (parser->flags & F_CHUNKED) {
+ if (!allow_chunked_length) {
+ SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH);
+ goto error;
+ }
+ } else if (!lenient) {
SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH);
goto error;
}
@@ -1886,7 +1896,7 @@ reexecute:
/* chunked encoding - ignore Content-Length header,
* prepare for a chunk */
UPDATE_STATE(s_chunk_size_start);
- } else if (parser->flags & F_TRANSFER_ENCODING) {
+ } else if (parser->uses_transfer_encoding == 1) {
if (parser->type == HTTP_REQUEST && !lenient) {
/* RFC 7230 3.3.3 */
@@ -2162,7 +2172,7 @@ http_message_needs_eof (const http_parser *parser)
}
/* RFC 7230 3.3.3, see `s_headers_almost_done` */
- if ((parser->flags & F_TRANSFER_ENCODING) &&
+ if ((parser->uses_transfer_encoding == 1) &&
(parser->flags & F_CHUNKED) == 0) {
return 1;
}
@@ -2514,7 +2524,7 @@ http_parser_parse_url(const char *buf, size_t buflen, int is_connect,
end = buf + off + len;
/* NOTE: The characters are already validated and are in the [0-9] range */
- assert(off + len <= buflen && "Port number overflow");
+ assert((size_t) (off + len) <= buflen && "Port number overflow");
v = 0;
for (p = buf + off; p < end; p++) {
v *= 10;
diff --git a/deps/http_parser/http_parser.h b/deps/http_parser/http_parser.h
index 983d88a910..3772b3994f 100644
--- a/deps/http_parser/http_parser.h
+++ b/deps/http_parser/http_parser.h
@@ -27,7 +27,7 @@ extern "C" {
/* Also update SONAME in the Makefile whenever you change these. */
#define HTTP_PARSER_VERSION_MAJOR 2
#define HTTP_PARSER_VERSION_MINOR 9
-#define HTTP_PARSER_VERSION_PATCH 3
+#define HTTP_PARSER_VERSION_PATCH 4
#include <stddef.h>
#if defined(_WIN32) && !defined(__MINGW32__) && \
@@ -41,6 +41,8 @@ typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
+#elif (defined(__sun) || defined(__sun__)) && defined(__SunOS_5_9)
+#include <sys/inttypes.h>
#else
#include <stdint.h>
#endif
@@ -225,7 +227,6 @@ enum flags
, F_UPGRADE = 1 << 5
, F_SKIPBODY = 1 << 6
, F_CONTENTLENGTH = 1 << 7
- , F_TRANSFER_ENCODING = 1 << 8
};
@@ -272,13 +273,13 @@ enum flags
"unexpected content-length header") \
XX(INVALID_CHUNK_SIZE, \
"invalid character in chunk size header") \
- XX(INVALID_TRANSFER_ENCODING, \
- "request has invalid transfer-encoding") \
XX(INVALID_CONSTANT, "invalid constant string") \
XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
XX(STRICT, "strict mode assertion failed") \
XX(PAUSED, "parser is paused") \
- XX(UNKNOWN, "an unknown error occurred")
+ XX(UNKNOWN, "an unknown error occurred") \
+ XX(INVALID_TRANSFER_ENCODING, \
+ "request has invalid transfer-encoding") \
/* Define HPE_* values for each errno value above */
@@ -296,14 +297,20 @@ enum http_errno {
struct http_parser {
/** PRIVATE **/
unsigned int type : 2; /* enum http_parser_type */
+ unsigned int flags : 8; /* F_* values from 'flags' enum; semi-public */
unsigned int state : 7; /* enum state from http_parser.c */
unsigned int header_state : 7; /* enum header_state from http_parser.c */
- unsigned int index : 7; /* index into current matcher */
+ unsigned int index : 5; /* index into current matcher */
+ unsigned int uses_transfer_encoding : 1; /* Transfer-Encoding header is present */
+ unsigned int allow_chunked_length : 1; /* Allow headers with both
+ * `Content-Length` and
+ * `Transfer-Encoding: chunked` set */
unsigned int lenient_http_headers : 1;
- unsigned int flags : 16; /* F_* values from 'flags' enum; semi-public */
uint32_t nread; /* # bytes read in various scenarios */
- uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */
+ uint64_t content_length; /* # bytes in body. `(uint64_t) -1` (all bits one)
+ * if no Content-Length header.
+ */
/** READ-ONLY **/
unsigned short http_major;
diff --git a/deps/http_parser/test.c b/deps/http_parser/test.c
index c979467cf7..3f7c77b349 100644
--- a/deps/http_parser/test.c
+++ b/deps/http_parser/test.c
@@ -74,6 +74,7 @@ struct message {
unsigned short http_major;
unsigned short http_minor;
+ uint64_t content_length;
int message_begin_cb_called;
int headers_complete_cb_called;
@@ -81,6 +82,7 @@ struct message {
int status_cb_called;
int message_complete_on_eof;
int body_is_final;
+ int allow_chunked_length;
};
static int currently_parsing_eof;
@@ -108,6 +110,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/test"
,.request_url= "/test"
+ ,.content_length= -1
,.num_headers= 3
,.headers=
{ { "User-Agent", "curl/7.18.0 (i486-pc-linux-gnu) libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1" }
@@ -139,6 +142,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/favicon.ico"
,.request_url= "/favicon.ico"
+ ,.content_length= -1
,.num_headers= 8
,.headers=
{ { "Host", "0.0.0.0=5000" }
@@ -168,6 +172,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/dumbluck"
,.request_url= "/dumbluck"
+ ,.content_length= -1
,.num_headers= 1
,.headers=
{ { "aaaaaaaaaaaaa", "++++++++++" }
@@ -190,6 +195,7 @@ const struct message requests[] =
,.request_path= "/forums/1/topics/2375"
/* XXX request url does include fragment? */
,.request_url= "/forums/1/topics/2375?page=1#posts-17408"
+ ,.content_length= -1
,.num_headers= 0
,.body= ""
}
@@ -208,6 +214,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/get_no_headers_no_body/world"
,.request_url= "/get_no_headers_no_body/world"
+ ,.content_length= -1
,.num_headers= 0
,.body= ""
}
@@ -227,6 +234,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/get_one_header_no_body"
,.request_url= "/get_one_header_no_body"
+ ,.content_length= -1
,.num_headers= 1
,.headers=
{ { "Accept" , "*/*" }
@@ -250,6 +258,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/get_funky_content_length_body_hello"
,.request_url= "/get_funky_content_length_body_hello"
+ ,.content_length= 5
,.num_headers= 1
,.headers=
{ { "conTENT-Length" , "5" }
@@ -274,6 +283,7 @@ const struct message requests[] =
,.fragment= "hey"
,.request_path= "/post_identity_body_world"
,.request_url= "/post_identity_body_world?q=search#hey"
+ ,.content_length= 5
,.num_headers= 2
,.headers=
{ { "Accept", "*/*" }
@@ -300,6 +310,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/post_chunked_all_your_base"
,.request_url= "/post_chunked_all_your_base"
+ ,.content_length= -1
,.num_headers= 1
,.headers=
{ { "Transfer-Encoding" , "chunked" }
@@ -328,6 +339,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/two_chunks_mult_zero_end"
,.request_url= "/two_chunks_mult_zero_end"
+ ,.content_length= -1
,.num_headers= 1
,.headers=
{ { "Transfer-Encoding", "chunked" }
@@ -358,6 +370,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/chunked_w_trailing_headers"
,.request_url= "/chunked_w_trailing_headers"
+ ,.content_length= -1
,.num_headers= 3
,.headers=
{ { "Transfer-Encoding", "chunked" }
@@ -388,6 +401,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/chunked_w_nonsense_after_length"
,.request_url= "/chunked_w_nonsense_after_length"
+ ,.content_length= -1
,.num_headers= 1
,.headers=
{ { "Transfer-Encoding", "chunked" }
@@ -410,6 +424,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/with_\"stupid\"_quotes"
,.request_url= "/with_\"stupid\"_quotes?foo=\"bar\""
+ ,.content_length= -1
,.num_headers= 0
,.headers= { }
,.body= ""
@@ -436,6 +451,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/test"
,.request_url= "/test"
+ ,.content_length= -1
,.num_headers= 3
,.headers= { { "Host", "0.0.0.0:5000" }
, { "User-Agent", "ApacheBench/2.3" }
@@ -459,6 +475,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/test.cgi"
,.request_url= "/test.cgi?foo=bar?baz"
+ ,.content_length= -1
,.num_headers= 0
,.headers= {}
,.body= ""
@@ -480,6 +497,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/test"
,.request_url= "/test"
+ ,.content_length= -1
,.num_headers= 0
,.headers= { }
,.body= ""
@@ -507,6 +525,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/demo"
,.request_url= "/demo"
+ ,.content_length= -1
,.num_headers= 7
,.upgrade="Hot diggity dogg"
,.headers= { { "Host", "example.com" }
@@ -538,6 +557,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= ""
,.request_url= "0-home0.netscape.com:443"
+ ,.content_length= -1
,.num_headers= 2
,.upgrade="some data\r\nand yet even more data"
,.headers= { { "User-agent", "Mozilla/1.1N" }
@@ -560,6 +580,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/test"
,.request_url= "/test"
+ ,.content_length= -1
,.num_headers= 0
,.headers= {}
,.body= ""
@@ -579,6 +600,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/"
,.request_url= "/"
+ ,.content_length= -1
,.num_headers= 0
,.headers= {}
,.body= ""
@@ -601,6 +623,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "*"
,.request_url= "*"
+ ,.content_length= -1
,.num_headers= 3
,.headers= { { "HOST", "239.255.255.250:1900" }
, { "MAN", "\"ssdp:discover\"" }
@@ -636,6 +659,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/"
,.request_url= "/"
+ ,.content_length= -1
,.num_headers= 5
,.headers= { { "Line1", "abc\tdef ghi\t\tjkl mno \t \tqrs" }
, { "Line2", "line2\t" }
@@ -662,6 +686,7 @@ const struct message requests[] =
,.request_path= ""
,.request_url= "http://hypnotoad.org?hail=all"
,.host= "hypnotoad.org"
+ ,.content_length= -1
,.num_headers= 0
,.headers= { }
,.body= ""
@@ -683,6 +708,7 @@ const struct message requests[] =
,.request_url= "http://hypnotoad.org:1234?hail=all"
,.host= "hypnotoad.org"
,.port= 1234
+ ,.content_length= -1
,.num_headers= 0
,.headers= { }
,.body= ""
@@ -704,6 +730,7 @@ const struct message requests[] =
,.request_url= "http://hypnotoad.org:1234"
,.host= "hypnotoad.org"
,.port= 1234
+ ,.content_length= -1
,.num_headers= 0
,.headers= { }
,.body= ""
@@ -728,6 +755,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/file.txt"
,.request_url= "/file.txt"
+ ,.content_length= 10
,.num_headers= 4
,.headers= { { "Host", "www.example.com" }
, { "Content-Type", "application/example" }
@@ -753,6 +781,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= ""
,.request_url= "HOME0.NETSCAPE.COM:443"
+ ,.content_length= -1
,.num_headers= 2
,.upgrade=""
,.headers= { { "User-agent", "Mozilla/1.1N" }
@@ -777,6 +806,7 @@ const struct message requests[] =
,.fragment= "narf"
,.request_path= "/δ¶/δt/pope"
,.request_url= "/δ¶/δt/pope?q=1#narf"
+ ,.content_length= -1
,.num_headers= 1
,.headers= { {"Host", "github.com" }
}
@@ -799,6 +829,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= ""
,.request_url= "home_0.netscape.com:443"
+ ,.content_length= -1
,.num_headers= 2
,.upgrade=""
,.headers= { { "User-agent", "Mozilla/1.1N" }
@@ -826,6 +857,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/"
,.request_url= "/"
+ ,.content_length= 4
,.num_headers= 3
,.upgrade= 0
,.headers= { { "Host", "www.example.com" }
@@ -854,6 +886,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/"
,.request_url= "/"
+ ,.content_length= 4
,.num_headers= 4
,.upgrade= 0
,.headers= { { "Host", "www.example.com" }
@@ -879,6 +912,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/file.txt"
,.request_url= "/file.txt"
+ ,.content_length= -1
,.num_headers= 1
,.headers= { { "Host", "www.example.com" } }
,.body= ""
@@ -899,6 +933,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/"
,.request_url= "/"
+ ,.content_length= -1
,.num_headers= 1
,.headers= { { "Host", "www.example.com" } }
,.body= ""
@@ -920,6 +955,7 @@ const struct message requests[] =
,.host= "hypnotoad.org"
,.userinfo= "a%12:b!&*$"
,.port= 1234
+ ,.content_length= -1
,.num_headers= 0
,.headers= { }
,.body= ""
@@ -952,6 +988,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/"
,.request_url= "/"
+ ,.content_length= -1
,.num_headers= 5
,.headers= { { "Line1", "abc\tdef ghi\t\tjkl mno \t \tqrs" }
, { "Line2", "line2\t" }
@@ -985,6 +1022,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/demo"
,.request_url= "/demo"
+ ,.content_length= -1
,.num_headers= 7
,.upgrade="Hot diggity dogg"
,.headers= { { "Host", "example.com" }
@@ -1015,6 +1053,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/demo"
,.request_url= "/demo"
+ ,.content_length= -1
,.num_headers= 2
,.upgrade="Hot diggity dogg"
,.headers= { { "Connection", "keep-alive, upgrade" }
@@ -1040,6 +1079,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/demo"
,.request_url= "/demo"
+ ,.content_length= -1
,.num_headers= 2
,.upgrade="Hot diggity dogg"
,.headers= { { "Connection", "keep-alive, upgrade" }
@@ -1066,6 +1106,7 @@ const struct message requests[] =
,.method= HTTP_POST
,.request_path= "/demo"
,.request_url= "/demo"
+ ,.content_length= 15
,.num_headers= 4
,.upgrade="Hot diggity dogg"
,.headers= { { "Host", "example.com" }
@@ -1091,6 +1132,7 @@ const struct message requests[] =
,.http_minor= 0
,.method= HTTP_CONNECT
,.request_url= "foo.bar.com:443"
+ ,.content_length= 10
,.num_headers= 3
,.upgrade="blarfcicle"
,.headers= { { "User-agent", "Mozilla/1.1N" }
@@ -1121,6 +1163,7 @@ const struct message requests[] =
,.request_url= "/images/my_dog.jpg"
,.query_string= ""
,.fragment= ""
+ ,.content_length= -1
,.num_headers= 3
,.headers= { { "Host", "example.com" }
, { "Link", "<http://example.com/profiles/joe>; rel=\"tag\"" }
@@ -1145,6 +1188,7 @@ const struct message requests[] =
,.request_url= "/images/my_dog.jpg"
,.query_string= ""
,.fragment= ""
+ ,.content_length= -1
,.num_headers= 2
,.headers= { { "Host", "example.com" }
, { "Link", "<http://example.com/profiles/sally>; rel=\"tag\"" }
@@ -1167,12 +1211,13 @@ const struct message requests[] =
,.request_url= "/music/sweet/music"
,.query_string= ""
,.fragment= ""
+ ,.content_length= -1
,.num_headers= 1
,.headers= { { "Host", "example.com" } }
,.body= ""
}
-#define SOURCE_ICE_REQUEST 42
+#define SOURCE_ICE_REQUEST 43
, {.name = "source request"
,.type= HTTP_REQUEST
,.raw= "SOURCE /music/sweet/music ICE/1.0\r\n"
@@ -1187,12 +1232,13 @@ const struct message requests[] =
,.request_url= "/music/sweet/music"
,.query_string= ""
,.fragment= ""
+ ,.content_length= -1
,.num_headers= 1
,.headers= { { "Host", "example.com" } }
,.body= ""
}
-#define POST_MULTI_TE_LAST_CHUNKED 43
+#define POST_MULTI_TE_LAST_CHUNKED 44
, {.name= "post - multi coding transfer-encoding chunked body"
,.type= HTTP_REQUEST
,.raw= "POST / HTTP/1.1\r\n"
@@ -1210,6 +1256,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/"
,.request_url= "/"
+ ,.content_length= -1
,.num_headers= 1
,.headers=
{ { "Transfer-Encoding" , "deflate, chunked" }
@@ -1219,8 +1266,8 @@ const struct message requests[] =
,.chunk_lengths= { 0x1e }
}
-#define POST_MULTI_LINE_TE_LAST_CHUNKED 43
-, {.name= "post - multi coding transfer-encoding chunked body"
+#define POST_MULTI_LINE_TE_LAST_CHUNKED 45
+, {.name= "post - multi line coding transfer-encoding chunked body"
,.type= HTTP_REQUEST
,.raw= "POST / HTTP/1.1\r\n"
"Transfer-Encoding: deflate,\r\n"
@@ -1238,6 +1285,7 @@ const struct message requests[] =
,.fragment= ""
,.request_path= "/"
,.request_url= "/"
+ ,.content_length= -1
,.num_headers= 1
,.headers=
{ { "Transfer-Encoding" , "deflate, chunked" }
@@ -1246,6 +1294,37 @@ const struct message requests[] =
,.num_chunks_complete= 2
,.chunk_lengths= { 0x1e }
}
+
+#define CHUNKED_CONTENT_LENGTH 46
+, {.name= "chunked with content-length set, allow_chunked_length flag is set"
+ ,.type= HTTP_REQUEST
+ ,.raw= "POST /chunked_w_content_length HTTP/1.1\r\n"
+ "Content-Length: 10\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "\r\n"
+ "5; ilovew3;whattheluck=aretheseparametersfor\r\nhello\r\n"
+ "6; blahblah; blah\r\n world\r\n"
+ "0\r\n"
+ "\r\n"
+ ,.allow_chunked_length = 1
+ ,.should_keep_alive= TRUE
+ ,.message_complete_on_eof= FALSE
+ ,.http_major= 1
+ ,.http_minor= 1
+ ,.method= HTTP_POST
+ ,.query_string= ""
+ ,.fragment= ""
+ ,.request_path= "/chunked_w_content_length"
+ ,.request_url= "/chunked_w_content_length"
+ ,.content_length= 10
+ ,.num_headers= 2
+ ,.headers={ { "Content-Length", "10"}
+ , { "Transfer-Encoding", "chunked" }
+ }
+ ,.body= "hello world"
+ ,.num_chunks_complete= 3
+ ,.chunk_lengths= { 5, 6 }
+ }
};
/* * R E S P O N S E S * */
@@ -1275,6 +1354,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 301
,.response_status= "Moved Permanently"
+ ,.content_length= 219
,.num_headers= 8
,.headers=
{ { "Location", "http://www.google.com/" }
@@ -1324,6 +1404,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 200
,.response_status= "OK"
+ ,.content_length= -1
,.num_headers= 5
,.headers=
{ { "Date", "Tue, 04 Aug 2009 07:59:32 GMT" }
@@ -1353,6 +1434,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 404
,.response_status= "Not Found"
+ ,.content_length= -1
,.num_headers= 0
,.headers= {}
,.body_size= 0
@@ -1368,6 +1450,7 @@ const struct message responses[] =
,.http_major= 1
,.http_minor= 1
,.status_code= 301
+ ,.content_length= -1
,.response_status= ""
,.num_headers= 0
,.headers= {}
@@ -1395,6 +1478,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 200
,.response_status= "OK"
+ ,.content_length= -1
,.num_headers= 2
,.headers=
{ {"Content-Type", "text/plain" }
@@ -1422,6 +1506,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 200
,.response_status= "OK"
+ ,.content_length= -1
,.num_headers= 2
,.headers=
{ {"Content-Type", "text/html; charset=utf-8" }
@@ -1446,6 +1531,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 200
,.response_status= "OK"
+ ,.content_length= 11
,.num_headers= 4
,.headers=
{ {"Content-Type", "text/html; charset=UTF-8" }
@@ -1472,6 +1558,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 200
,.response_status= "OK"
+ ,.content_length= 0
,.num_headers= 4
,.headers=
{ {"Server", "DCLK-AdSvr" }
@@ -1505,6 +1592,7 @@ const struct message responses[] =
,.http_minor= 0
,.status_code= 301
,.response_status= "Moved Permanently"
+ ,.content_length= 0
,.num_headers= 9
,.headers=
{ { "Date", "Thu, 03 Jun 2010 09:56:32 GMT" }
@@ -1544,6 +1632,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 200
,.response_status= "OK"
+ ,.content_length= -1
,.num_headers= 11
,.headers=
{ { "Date", "Tue, 28 Sep 2010 01:14:13 GMT" }
@@ -1578,6 +1667,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 500
,.response_status= "Oriëntatieprobleem"
+ ,.content_length= 0
,.num_headers= 3
,.headers=
{ { "Date", "Fri, 5 Nov 2010 23:07:12 GMT+2" }
@@ -1599,6 +1689,7 @@ const struct message responses[] =
,.http_minor= 9
,.status_code= 200
,.response_status= "OK"
+ ,.content_length= -1
,.num_headers= 0
,.headers=
{}
@@ -1622,6 +1713,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 200
,.response_status= "OK"
+ ,.content_length= -1
,.num_headers= 1
,.headers=
{ { "Content-Type", "text/plain" }
@@ -1641,6 +1733,7 @@ const struct message responses[] =
,.http_minor= 0
,.status_code= 200
,.response_status= "OK"
+ ,.content_length= -1
,.num_headers= 1
,.headers=
{ { "Connection", "keep-alive" }
@@ -1661,6 +1754,7 @@ const struct message responses[] =
,.http_minor= 0
,.status_code= 204
,.response_status= "No content"
+ ,.content_length= -1
,.num_headers= 1
,.headers=
{ { "Connection", "keep-alive" }
@@ -1680,6 +1774,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 200
,.response_status= "OK"
+ ,.content_length= -1
,.num_headers= 0
,.headers={}
,.body_size= 0
@@ -1697,6 +1792,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 204
,.response_status= "No content"
+ ,.content_length= -1
,.num_headers= 0
,.headers={}
,.body_size= 0
@@ -1715,6 +1811,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 204
,.response_status= "No content"
+ ,.content_length= -1
,.num_headers= 1
,.headers=
{ { "Connection", "close" }
@@ -1737,6 +1834,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 200
,.response_status= "OK"
+ ,.content_length= -1
,.num_headers= 1
,.headers=
{ { "Transfer-Encoding", "chunked" }
@@ -1767,6 +1865,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 200
,.response_status= "OK"
+ ,.content_length= 16
,.num_headers= 7
,.headers=
{ { "Server", "Microsoft-IIS/6.0" }
@@ -1805,6 +1904,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 301
,.response_status= "MovedPermanently"
+ ,.content_length= -1
,.num_headers= 9
,.headers= { { "Date", "Wed, 15 May 2013 17:06:33 GMT" }
, { "Server", "Server" }
@@ -1821,7 +1921,7 @@ const struct message responses[] =
,.chunk_lengths= { 1 }
}
-#define EMPTY_REASON_PHRASE_AFTER_SPACE 20
+#define EMPTY_REASON_PHRASE_AFTER_SPACE 21
, {.name= "empty reason phrase after space"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 200 \r\n"
@@ -1832,12 +1932,13 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 200
,.response_status= ""
+ ,.content_length= -1
,.num_headers= 0
,.headers= {}
,.body= ""
}
-#define CONTENT_LENGTH_X 21
+#define CONTENT_LENGTH_X 22
, {.name= "Content-Length-X"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 200 OK\r\n"
@@ -1854,6 +1955,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 200
,.response_status= "OK"
+ ,.content_length= -1
,.num_headers= 2
,.headers= { { "Content-Length-X", "0" }
, { "Transfer-Encoding", "chunked" }
@@ -1863,7 +1965,7 @@ const struct message responses[] =
,.chunk_lengths= { 2 }
}
-#define HTTP_101_RESPONSE_WITH_UPGRADE_HEADER 22
+#define HTTP_101_RESPONSE_WITH_UPGRADE_HEADER 23
, {.name= "HTTP 101 response with Upgrade header"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 101 Switching Protocols\r\n"
@@ -1878,6 +1980,7 @@ const struct message responses[] =
,.status_code= 101
,.response_status= "Switching Protocols"
,.upgrade= "proto"
+ ,.content_length= -1
,.num_headers= 2
,.headers=
{ { "Connection", "upgrade" }
@@ -1885,7 +1988,7 @@ const struct message responses[] =
}
}
-#define HTTP_101_RESPONSE_WITH_UPGRADE_HEADER_AND_CONTENT_LENGTH 23
+#define HTTP_101_RESPONSE_WITH_UPGRADE_HEADER_AND_CONTENT_LENGTH 24
, {.name= "HTTP 101 response with Upgrade and Content-Length header"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 101 Switching Protocols\r\n"
@@ -1903,6 +2006,7 @@ const struct message responses[] =
,.response_status= "Switching Protocols"
,.body= "body"
,.upgrade= "proto"
+ ,.content_length= 4
,.num_headers= 3
,.headers=
{ { "Connection", "upgrade" }
@@ -1911,7 +2015,7 @@ const struct message responses[] =
}
}
-#define HTTP_101_RESPONSE_WITH_UPGRADE_HEADER_AND_TRANSFER_ENCODING 24
+#define HTTP_101_RESPONSE_WITH_UPGRADE_HEADER_AND_TRANSFER_ENCODING 25
, {.name= "HTTP 101 response with Upgrade and Transfer-Encoding header"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 101 Switching Protocols\r\n"
@@ -1934,6 +2038,7 @@ const struct message responses[] =
,.response_status= "Switching Protocols"
,.body= "body"
,.upgrade= "proto"
+ ,.content_length= -1
,.num_headers= 3
,.headers=
{ { "Connection", "upgrade" }
@@ -1944,7 +2049,7 @@ const struct message responses[] =
,.chunk_lengths= { 2, 2 }
}
-#define HTTP_200_RESPONSE_WITH_UPGRADE_HEADER 25
+#define HTTP_200_RESPONSE_WITH_UPGRADE_HEADER 26
, {.name= "HTTP 200 response with Upgrade header"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 200 OK\r\n"
@@ -1960,6 +2065,7 @@ const struct message responses[] =
,.response_status= "OK"
,.body= "body"
,.upgrade= NULL
+ ,.content_length= -1
,.num_headers= 2
,.headers=
{ { "Connection", "upgrade" }
@@ -1967,7 +2073,7 @@ const struct message responses[] =
}
}
-#define HTTP_200_RESPONSE_WITH_UPGRADE_HEADER_AND_CONTENT_LENGTH 26
+#define HTTP_200_RESPONSE_WITH_UPGRADE_HEADER_AND_CONTENT_LENGTH 27
, {.name= "HTTP 200 response with Upgrade and Content-Length header"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 200 OK\r\n"
@@ -1982,6 +2088,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 200
,.response_status= "OK"
+ ,.content_length= 4
,.num_headers= 3
,.body= "body"
,.upgrade= NULL
@@ -1992,7 +2099,7 @@ const struct message responses[] =
}
}
-#define HTTP_200_RESPONSE_WITH_UPGRADE_HEADER_AND_TRANSFER_ENCODING 27
+#define HTTP_200_RESPONSE_WITH_UPGRADE_HEADER_AND_TRANSFER_ENCODING 28
, {.name= "HTTP 200 response with Upgrade and Transfer-Encoding header"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 200 OK\r\n"
@@ -2012,6 +2119,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 200
,.response_status= "OK"
+ ,.content_length= -1
,.num_headers= 3
,.body= "body"
,.upgrade= NULL
@@ -2023,7 +2131,7 @@ const struct message responses[] =
,.num_chunks_complete= 3
,.chunk_lengths= { 2, 2 }
}
-#define HTTP_200_MULTI_TE_NOT_LAST_CHUNKED 28
+#define HTTP_200_MULTI_TE_NOT_LAST_CHUNKED 29
, {.name= "HTTP 200 response with `chunked` being *not last* Transfer-Encoding"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 200 OK\r\n"
@@ -2039,6 +2147,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 200
,.response_status= "OK"
+ ,.content_length= -1
,.num_headers= 1
,.headers= { { "Transfer-Encoding", "chunked, identity" }
}
@@ -2202,6 +2311,7 @@ headers_complete_cb (http_parser *p)
messages[num_messages].status_code = parser.status_code;
messages[num_messages].http_major = parser.http_major;
messages[num_messages].http_minor = parser.http_minor;
+ messages[num_messages].content_length = parser.content_length;
messages[num_messages].headers_complete_cb_called = TRUE;
messages[num_messages].should_keep_alive = http_should_keep_alive(&parser);
return 0;
@@ -2650,6 +2760,7 @@ message_eq (int index, int connect, const struct message *expected)
MESSAGE_CHECK_NUM_EQ(expected, m, http_major);
MESSAGE_CHECK_NUM_EQ(expected, m, http_minor);
+ MESSAGE_CHECK_NUM_EQ(expected, m, content_length);
if (expected->type == HTTP_REQUEST) {
MESSAGE_CHECK_NUM_EQ(expected, m, method);
@@ -3503,6 +3614,9 @@ test_message (const struct message *message)
size_t msg1len;
for (msg1len = 0; msg1len < raw_len; msg1len++) {
parser_init(message->type);
+ if (message->allow_chunked_length) {
+ parser.allow_chunked_length = 1;
+ }
size_t read;
const char *msg1 = message->raw;
@@ -3944,6 +4058,11 @@ test_multiple3 (const struct message *r1, const struct message *r2, const struct
strcat(total, r3->raw);
parser_init(r1->type);
+ if (r1->allow_chunked_length ||
+ r2->allow_chunked_length ||
+ r3->allow_chunked_length) {
+ parser.allow_chunked_length = 1;
+ }
size_t read;
@@ -4146,6 +4265,9 @@ test_message_pause (const struct message *msg)
size_t nread;
parser_init(msg->type);
+ if (msg->allow_chunked_length) {
+ parser.allow_chunked_length = 1;
+ }
do {
nread = parse_pause(buf, buflen);
@@ -4222,6 +4344,13 @@ main (void)
printf("sizeof(http_parser) = %u\n", (unsigned int)sizeof(http_parser));
+#if defined(__i386__) || defined(__x86_64__)
+ /* Should be 32 on both 32 bits and 64 bits x86 because of struct padding,
+ * see https://github.com/nodejs/http-parser/issues/507.
+ */
+ assert(sizeof(http_parser) == 32);
+#endif
+
//// API
test_preserve_data();
test_parse_url();
@@ -4350,6 +4479,7 @@ main (void)
,.http_minor= 0
,.status_code= 200
,.response_status= "OK"
+ ,.content_length= -1
,.num_headers= 2
,.headers=
{ { "Transfer-Encoding", "chunked" }