Browse Source

Cherry-pick commits from upstream that seem sensible to include

* "Fix test numbers"
* "Fix -Wsign-compare warning"
* "Test Content-Length header parsing"
* "Allow Content-Length and Transfer-Encoding: chunked"
Christoph Biedl 3 years ago
parent
commit
c36f8f68d9

+ 118 - 0
debian/patches/cherry-pick.v2.9.4-4-g805a0d1.fix-test-numbers.patch

@@ -0,0 +1,118 @@
+Subject: Fix test numbers
+Origin: v2.9.4-4-g805a0d1 <https://github.com/joyent/http-parser/commit/805a0d1>
+Upstream-Author: Derek Argueta <deargueta@tesla.com>
+Date: Mon May 4 02:11:29 2020 -0700
+
+    PR-URL: https://github.com/nodejs/http-parser/pull/511
+    Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
+
+--- a/test.c
++++ b/test.c
+@@ -1172,7 +1172,7 @@
+   ,.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"
+@@ -1192,7 +1192,7 @@
+   ,.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"
+@@ -1219,7 +1219,7 @@
+   ,.chunk_lengths= { 0x1e }
+   }
+ 
+-#define POST_MULTI_LINE_TE_LAST_CHUNKED 44
++#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"
+@@ -1821,7 +1821,7 @@
+   ,.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"
+@@ -1837,7 +1837,7 @@
+   ,.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"
+@@ -1863,7 +1863,7 @@
+   ,.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"
+@@ -1885,7 +1885,7 @@
+     }
+   }
+ 
+-#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"
+@@ -1911,7 +1911,7 @@
+     }
+   }
+ 
+-#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"
+@@ -1944,7 +1944,7 @@
+   ,.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"
+@@ -1967,7 +1967,7 @@
+     }
+   }
+ 
+-#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"
+@@ -1992,7 +1992,7 @@
+     }
+   }
+ 
+-#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"
+@@ -2023,7 +2023,7 @@
+   ,.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"

+ 24 - 0
debian/patches/cherry-pick.v2.9.4-6-gd9275da.fix-wsign-compare-warning.patch

@@ -0,0 +1,24 @@
+Subject: Fix -Wsign-compare warning
+Origin: v2.9.4-6-gd9275da <https://github.com/joyent/http-parser/commit/d9275da>
+Upstream-Author: Ben Noordhuis <info@bnoordhuis.nl>
+Date: Fri May 15 13:29:49 2020 +0200
+
+    The operands to `+` are promoted from `uint16_t` to `int` before
+    addition, making the expression `off + len <= buflen` emit a
+    warning because `buflen` is unsigned.
+
+    Fixes: https://github.com/nodejs/http-parser/issues/514
+    PR-URL: https://github.com/nodejs/http-parser/pull/515
+    Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
+
+--- a/http_parser.c
++++ b/http_parser.c
+@@ -2517,7 +2517,7 @@
+     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;

+ 654 - 0
debian/patches/cherry-pick.v2.9.4-7-g4b99e42.test-content-length-header-parsing.patch

@@ -0,0 +1,654 @@
+Subject: Test Content-Length header parsing
+Origin: v2.9.4-7-g4b99e42 <https://github.com/joyent/http-parser/commit/4b99e42>
+Upstream-Author: Ben Noordhuis <info@bnoordhuis.nl>
+Date: Wed Jul 8 02:30:29 2020 +0200
+
+    The test suite did very little validation of the Content-Length field
+    until now. Verify for each request and response that the parsed numeric
+    value matches the value from the header field.
+
+    PR-URL: https://github.com/nodejs/http-parser/pull/519
+    Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
+
+--- a/test.c
++++ b/test.c
+@@ -74,6 +74,7 @@
+ 
+   unsigned short http_major;
+   unsigned short http_minor;
++  uint64_t content_length;
+ 
+   int message_begin_cb_called;
+   int headers_complete_cb_called;
+@@ -108,6 +109,7 @@
+   ,.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 +141,7 @@
+   ,.fragment= ""
+   ,.request_path= "/favicon.ico"
+   ,.request_url= "/favicon.ico"
++  ,.content_length= -1
+   ,.num_headers= 8
+   ,.headers=
+     { { "Host", "0.0.0.0=5000" }
+@@ -168,6 +171,7 @@
+   ,.fragment= ""
+   ,.request_path= "/dumbluck"
+   ,.request_url= "/dumbluck"
++  ,.content_length= -1
+   ,.num_headers= 1
+   ,.headers=
+     { { "aaaaaaaaaaaaa",  "++++++++++" }
+@@ -190,6 +194,7 @@
+   ,.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 +213,7 @@
+   ,.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 +233,7 @@
+   ,.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 +257,7 @@
+   ,.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 +282,7 @@
+   ,.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 +309,7 @@
+   ,.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 +338,7 @@
+   ,.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 +369,7 @@
+   ,.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 +400,7 @@
+   ,.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 +423,7 @@
+   ,.fragment= ""
+   ,.request_path= "/with_\"stupid\"_quotes"
+   ,.request_url= "/with_\"stupid\"_quotes?foo=\"bar\""
++  ,.content_length= -1
+   ,.num_headers= 0
+   ,.headers= { }
+   ,.body= ""
+@@ -436,6 +450,7 @@
+   ,.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 +474,7 @@
+   ,.fragment= ""
+   ,.request_path= "/test.cgi"
+   ,.request_url= "/test.cgi?foo=bar?baz"
++  ,.content_length= -1
+   ,.num_headers= 0
+   ,.headers= {}
+   ,.body= ""
+@@ -480,6 +496,7 @@
+   ,.fragment= ""
+   ,.request_path= "/test"
+   ,.request_url= "/test"
++  ,.content_length= -1
+   ,.num_headers= 0
+   ,.headers= { }
+   ,.body= ""
+@@ -507,6 +524,7 @@
+   ,.fragment= ""
+   ,.request_path= "/demo"
+   ,.request_url= "/demo"
++  ,.content_length= -1
+   ,.num_headers= 7
+   ,.upgrade="Hot diggity dogg"
+   ,.headers= { { "Host", "example.com" }
+@@ -538,6 +556,7 @@
+   ,.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 +579,7 @@
+   ,.fragment= ""
+   ,.request_path= "/test"
+   ,.request_url= "/test"
++  ,.content_length= -1
+   ,.num_headers= 0
+   ,.headers= {}
+   ,.body= ""
+@@ -579,6 +599,7 @@
+   ,.fragment= ""
+   ,.request_path= "/"
+   ,.request_url= "/"
++  ,.content_length= -1
+   ,.num_headers= 0
+   ,.headers= {}
+   ,.body= ""
+@@ -601,6 +622,7 @@
+   ,.fragment= ""
+   ,.request_path= "*"
+   ,.request_url= "*"
++  ,.content_length= -1
+   ,.num_headers= 3
+   ,.headers= { { "HOST", "239.255.255.250:1900" }
+              , { "MAN", "\"ssdp:discover\"" }
+@@ -636,6 +658,7 @@
+   ,.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 +685,7 @@
+   ,.request_path= ""
+   ,.request_url= "http://hypnotoad.org?hail=all"
+   ,.host= "hypnotoad.org"
++  ,.content_length= -1
+   ,.num_headers= 0
+   ,.headers= { }
+   ,.body= ""
+@@ -683,6 +707,7 @@
+   ,.request_url= "http://hypnotoad.org:1234?hail=all"
+   ,.host= "hypnotoad.org"
+   ,.port= 1234
++  ,.content_length= -1
+   ,.num_headers= 0
+   ,.headers= { }
+   ,.body= ""
+@@ -704,6 +729,7 @@
+   ,.request_url= "http://hypnotoad.org:1234"
+   ,.host= "hypnotoad.org"
+   ,.port= 1234
++  ,.content_length= -1
+   ,.num_headers= 0
+   ,.headers= { }
+   ,.body= ""
+@@ -728,6 +754,7 @@
+   ,.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 +780,7 @@
+   ,.fragment= ""
+   ,.request_path= ""
+   ,.request_url= "HOME0.NETSCAPE.COM:443"
++  ,.content_length= -1
+   ,.num_headers= 2
+   ,.upgrade=""
+   ,.headers= { { "User-agent", "Mozilla/1.1N" }
+@@ -777,6 +805,7 @@
+   ,.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 +828,7 @@
+   ,.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 +856,7 @@
+   ,.fragment= ""
+   ,.request_path= "/"
+   ,.request_url= "/"
++  ,.content_length= 4
+   ,.num_headers= 3
+   ,.upgrade= 0
+   ,.headers= { { "Host", "www.example.com" }
+@@ -854,6 +885,7 @@
+   ,.fragment= ""
+   ,.request_path= "/"
+   ,.request_url= "/"
++  ,.content_length= 4
+   ,.num_headers= 4
+   ,.upgrade= 0
+   ,.headers= { { "Host", "www.example.com" }
+@@ -879,6 +911,7 @@
+   ,.fragment= ""
+   ,.request_path= "/file.txt"
+   ,.request_url= "/file.txt"
++  ,.content_length= -1
+   ,.num_headers= 1
+   ,.headers= { { "Host", "www.example.com" } }
+   ,.body= ""
+@@ -899,6 +932,7 @@
+   ,.fragment= ""
+   ,.request_path= "/"
+   ,.request_url= "/"
++  ,.content_length= -1
+   ,.num_headers= 1
+   ,.headers= { { "Host", "www.example.com" } }
+   ,.body= ""
+@@ -920,6 +954,7 @@
+   ,.host= "hypnotoad.org"
+   ,.userinfo= "a%12:b!&*$"
+   ,.port= 1234
++  ,.content_length= -1
+   ,.num_headers= 0
+   ,.headers= { }
+   ,.body= ""
+@@ -952,6 +987,7 @@
+   ,.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 +1021,7 @@
+   ,.fragment= ""
+   ,.request_path= "/demo"
+   ,.request_url= "/demo"
++  ,.content_length= -1
+   ,.num_headers= 7
+   ,.upgrade="Hot diggity dogg"
+   ,.headers= { { "Host", "example.com" }
+@@ -1015,6 +1052,7 @@
+   ,.fragment= ""
+   ,.request_path= "/demo"
+   ,.request_url= "/demo"
++  ,.content_length= -1
+   ,.num_headers= 2
+   ,.upgrade="Hot diggity dogg"
+   ,.headers= { { "Connection", "keep-alive, upgrade" }
+@@ -1040,6 +1078,7 @@
+   ,.fragment= ""
+   ,.request_path= "/demo"
+   ,.request_url= "/demo"
++  ,.content_length= -1
+   ,.num_headers= 2
+   ,.upgrade="Hot diggity dogg"
+   ,.headers= { { "Connection", "keep-alive,  upgrade" }
+@@ -1066,6 +1105,7 @@
+   ,.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 +1131,7 @@
+   ,.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 +1162,7 @@
+   ,.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 +1187,7 @@
+   ,.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,6 +1210,7 @@
+   ,.request_url= "/music/sweet/music"
+   ,.query_string= ""
+   ,.fragment= ""
++  ,.content_length= -1
+   ,.num_headers= 1
+   ,.headers= { { "Host", "example.com" } }
+   ,.body= ""
+@@ -1187,6 +1231,7 @@
+   ,.request_url= "/music/sweet/music"
+   ,.query_string= ""
+   ,.fragment= ""
++  ,.content_length= -1
+   ,.num_headers= 1
+   ,.headers= { { "Host", "example.com" } }
+   ,.body= ""
+@@ -1210,6 +1255,7 @@
+   ,.fragment= ""
+   ,.request_path= "/"
+   ,.request_url= "/"
++  ,.content_length= -1
+   ,.num_headers= 1
+   ,.headers=
+     { { "Transfer-Encoding" , "deflate, chunked" }
+@@ -1238,6 +1284,7 @@
+   ,.fragment= ""
+   ,.request_path= "/"
+   ,.request_url= "/"
++  ,.content_length= -1
+   ,.num_headers= 1
+   ,.headers=
+     { { "Transfer-Encoding" , "deflate, chunked" }
+@@ -1275,6 +1322,7 @@
+   ,.http_minor= 1
+   ,.status_code= 301
+   ,.response_status= "Moved Permanently"
++  ,.content_length= 219
+   ,.num_headers= 8
+   ,.headers=
+     { { "Location", "http://www.google.com/" }
+@@ -1324,6 +1372,7 @@
+   ,.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 +1402,7 @@
+   ,.http_minor= 1
+   ,.status_code= 404
+   ,.response_status= "Not Found"
++  ,.content_length= -1
+   ,.num_headers= 0
+   ,.headers= {}
+   ,.body_size= 0
+@@ -1368,6 +1418,7 @@
+   ,.http_major= 1
+   ,.http_minor= 1
+   ,.status_code= 301
++  ,.content_length= -1
+   ,.response_status= ""
+   ,.num_headers= 0
+   ,.headers= {}
+@@ -1395,6 +1446,7 @@
+   ,.http_minor= 1
+   ,.status_code= 200
+   ,.response_status= "OK"
++  ,.content_length= -1
+   ,.num_headers= 2
+   ,.headers=
+     { {"Content-Type", "text/plain" }
+@@ -1422,6 +1474,7 @@
+   ,.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 +1499,7 @@
+   ,.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 +1526,7 @@
+   ,.http_minor= 1
+   ,.status_code= 200
+   ,.response_status= "OK"
++  ,.content_length= 0
+   ,.num_headers= 4
+   ,.headers=
+     { {"Server", "DCLK-AdSvr" }
+@@ -1505,6 +1560,7 @@
+   ,.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 +1600,7 @@
+   ,.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 +1635,7 @@
+   ,.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 +1657,7 @@
+   ,.http_minor= 9
+   ,.status_code= 200
+   ,.response_status= "OK"
++  ,.content_length= -1
+   ,.num_headers= 0
+   ,.headers=
+     {}
+@@ -1622,6 +1681,7 @@
+   ,.http_minor= 1
+   ,.status_code= 200
+   ,.response_status= "OK"
++  ,.content_length= -1
+   ,.num_headers= 1
+   ,.headers=
+     { { "Content-Type", "text/plain" }
+@@ -1641,6 +1701,7 @@
+   ,.http_minor= 0
+   ,.status_code= 200
+   ,.response_status= "OK"
++  ,.content_length= -1
+   ,.num_headers= 1
+   ,.headers=
+     { { "Connection", "keep-alive" }
+@@ -1661,6 +1722,7 @@
+   ,.http_minor= 0
+   ,.status_code= 204
+   ,.response_status= "No content"
++  ,.content_length= -1
+   ,.num_headers= 1
+   ,.headers=
+     { { "Connection", "keep-alive" }
+@@ -1680,6 +1742,7 @@
+   ,.http_minor= 1
+   ,.status_code= 200
+   ,.response_status= "OK"
++  ,.content_length= -1
+   ,.num_headers= 0
+   ,.headers={}
+   ,.body_size= 0
+@@ -1697,6 +1760,7 @@
+   ,.http_minor= 1
+   ,.status_code= 204
+   ,.response_status= "No content"
++  ,.content_length= -1
+   ,.num_headers= 0
+   ,.headers={}
+   ,.body_size= 0
+@@ -1715,6 +1779,7 @@
+   ,.http_minor= 1
+   ,.status_code= 204
+   ,.response_status= "No content"
++  ,.content_length= -1
+   ,.num_headers= 1
+   ,.headers=
+     { { "Connection", "close" }
+@@ -1737,6 +1802,7 @@
+   ,.http_minor= 1
+   ,.status_code= 200
+   ,.response_status= "OK"
++  ,.content_length= -1
+   ,.num_headers= 1
+   ,.headers=
+     { { "Transfer-Encoding", "chunked" }
+@@ -1767,6 +1833,7 @@
+   ,.http_minor= 1
+   ,.status_code= 200
+   ,.response_status= "OK"
++  ,.content_length= 16
+   ,.num_headers= 7
+   ,.headers=
+     { { "Server",  "Microsoft-IIS/6.0" }
+@@ -1805,6 +1872,7 @@
+   ,.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" }
+@@ -1832,6 +1900,7 @@
+   ,.http_minor= 1
+   ,.status_code= 200
+   ,.response_status= ""
++  ,.content_length= -1
+   ,.num_headers= 0
+   ,.headers= {}
+   ,.body= ""
+@@ -1854,6 +1923,7 @@
+   ,.http_minor= 1
+   ,.status_code= 200
+   ,.response_status= "OK"
++  ,.content_length= -1
+   ,.num_headers= 2
+   ,.headers= { { "Content-Length-X", "0" }
+              , { "Transfer-Encoding", "chunked" }
+@@ -1878,6 +1948,7 @@
+   ,.status_code= 101
+   ,.response_status= "Switching Protocols"
+   ,.upgrade= "proto"
++  ,.content_length= -1
+   ,.num_headers= 2
+   ,.headers=
+     { { "Connection", "upgrade" }
+@@ -1903,6 +1974,7 @@
+   ,.response_status= "Switching Protocols"
+   ,.body= "body"
+   ,.upgrade= "proto"
++  ,.content_length= 4
+   ,.num_headers= 3
+   ,.headers=
+     { { "Connection", "upgrade" }
+@@ -1934,6 +2006,7 @@
+   ,.response_status= "Switching Protocols"
+   ,.body= "body"
+   ,.upgrade= "proto"
++  ,.content_length= -1
+   ,.num_headers= 3
+   ,.headers=
+     { { "Connection", "upgrade" }
+@@ -1960,6 +2033,7 @@
+   ,.response_status= "OK"
+   ,.body= "body"
+   ,.upgrade= NULL
++  ,.content_length= -1
+   ,.num_headers= 2
+   ,.headers=
+     { { "Connection", "upgrade" }
+@@ -1982,6 +2056,7 @@
+   ,.http_minor= 1
+   ,.status_code= 200
+   ,.response_status= "OK"
++  ,.content_length= 4
+   ,.num_headers= 3
+   ,.body= "body"
+   ,.upgrade= NULL
+@@ -2012,6 +2087,7 @@
+   ,.http_minor= 1
+   ,.status_code= 200
+   ,.response_status= "OK"
++  ,.content_length= -1
+   ,.num_headers= 3
+   ,.body= "body"
+   ,.upgrade= NULL
+@@ -2039,6 +2115,7 @@
+   ,.http_minor= 1
+   ,.status_code= 200
+   ,.response_status= "OK"
++  ,.content_length= -1
+   ,.num_headers= 1
+   ,.headers= { { "Transfer-Encoding", "chunked, identity" }
+              }
+@@ -2202,6 +2279,7 @@
+   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 +2728,7 @@
+ 
+   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);
+@@ -4351,6 +4430,7 @@
+       ,.http_minor= 0
+       ,.status_code= 200
+       ,.response_status= "OK"
++      ,.content_length= -1
+       ,.num_headers= 2
+       ,.headers=
+         { { "Transfer-Encoding", "chunked" }

+ 201 - 0
debian/patches/cherry-pick.v2.9.4-8-ge13b274.allow-content-length-and-transfer-encoding-chunked.patch

@@ -0,0 +1,201 @@
+Subject: Allow Content-Length and Transfer-Encoding: chunked
+Origin: v2.9.4-8-ge13b274 <https://github.com/joyent/http-parser/commit/e13b274>
+Upstream-Author: Oleg Guba <oleg@dropbox.com>
+Date: Fri Jul 10 11:49:58 2020 +0200
+
+    Fixes: https://github.com/nodejs/http-parser/issues/517
+    PR-URL: https://github.com/nodejs/http-parser/pull/518
+    Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
+    Reviewed-By: Pierce Lopez <pierce.lopez@gmail.com>
+
+--- a/http_parser.c
++++ b/http_parser.c
+@@ -653,6 +653,8 @@
+   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,7 +733,7 @@
+         if (ch == CR || ch == LF)
+           break;
+         parser->flags = 0;
+-        parser->extra_flags = 0;
++        parser->uses_transfer_encoding = 0;
+         parser->content_length = ULLONG_MAX;
+ 
+         if (ch == 'H') {
+@@ -769,7 +771,7 @@
+         if (ch == CR || ch == LF)
+           break;
+         parser->flags = 0;
+-        parser->extra_flags = 0;
++        parser->uses_transfer_encoding = 0;
+         parser->content_length = ULLONG_MAX;
+ 
+         if (ch == 'H') {
+@@ -927,7 +929,7 @@
+         if (ch == CR || ch == LF)
+           break;
+         parser->flags = 0;
+-        parser->extra_flags = 0;
++        parser->uses_transfer_encoding = 0;
+         parser->content_length = ULLONG_MAX;
+ 
+         if (UNLIKELY(!IS_ALPHA(ch))) {
+@@ -1341,7 +1343,7 @@
+                 parser->header_state = h_general;
+               } else if (parser->index == sizeof(TRANSFER_ENCODING)-2) {
+                 parser->header_state = h_transfer_encoding;
+-                parser->extra_flags |= F_TRANSFER_ENCODING >> 8;
++                parser->uses_transfer_encoding = 1;
+               }
+               break;
+ 
+@@ -1801,14 +1803,19 @@
+           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->extra_flags & (F_TRANSFER_ENCODING >> 8)) &&
++        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;
+           }
+@@ -1889,7 +1896,7 @@
+           /* chunked encoding - ignore Content-Length header,
+            * prepare for a chunk */
+           UPDATE_STATE(s_chunk_size_start);
+-        } else if (parser->extra_flags & (F_TRANSFER_ENCODING >> 8)) {
++        } else if (parser->uses_transfer_encoding == 1) {
+           if (parser->type == HTTP_REQUEST && !lenient) {
+             /* RFC 7230 3.3.3 */
+ 
+@@ -2165,7 +2172,7 @@
+   }
+ 
+   /* RFC 7230 3.3.3, see `s_headers_almost_done` */
+-  if ((parser->extra_flags & (F_TRANSFER_ENCODING >> 8)) &&
++  if ((parser->uses_transfer_encoding == 1) &&
+       (parser->flags & F_CHUNKED) == 0) {
+     return 1;
+   }
+--- a/http_parser.h
++++ b/http_parser.h
+@@ -225,7 +225,6 @@
+   , F_UPGRADE               = 1 << 5
+   , F_SKIPBODY              = 1 << 6
+   , F_CONTENTLENGTH         = 1 << 7
+-  , F_TRANSFER_ENCODING     = 1 << 8  /* Never set in http_parser.flags */
+   };
+ 
+ 
+@@ -300,7 +299,10 @@
+   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 : 5;        /* index into current matcher */
+-  unsigned int extra_flags : 2;
++  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;
+ 
+   uint32_t nread;          /* # bytes read in various scenarios */
+--- a/test.c
++++ b/test.c
+@@ -82,6 +82,7 @@
+   int status_cb_called;
+   int message_complete_on_eof;
+   int body_is_final;
++  int allow_chunked_length;
+ };
+ 
+ static int currently_parsing_eof;
+@@ -1293,6 +1294,37 @@
+   ,.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 * */
+@@ -3582,6 +3614,9 @@
+   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;
+@@ -4023,6 +4058,11 @@
+   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;
+ 
+@@ -4225,6 +4265,9 @@
+   size_t nread;
+ 
+   parser_init(msg->type);
++  if (msg->allow_chunked_length) {
++    parser.allow_chunked_length = 1;
++  }
+ 
+   do {
+     nread = parse_pause(buf, buflen);

+ 2 - 2
debian/patches/cherry-pick.v2.9.4-9-g4f15b7d.fix-sizeof-http-parser-assert.patch

@@ -1,5 +1,5 @@
 Subject: Fix sizeof(http_parser) assert
-Origin: v2.9.4-9-g4f15b7d <https://github.com/joyent/http-parser/commit/v2.9.4-9-g4f15b7d>
+Origin: v2.9.4-9-g4f15b7d <https://github.com/joyent/http-parser/commit/4f15b7d>
 Upstream-Author: Ben Noordhuis <info@bnoordhuis.nl>
 Date: Fri Jul 10 11:55:11 2020 +0200
 Bug: https://github.com/nodejs/http-parser/issues/526
@@ -14,7 +14,7 @@ Comment: Changed again to make build pass on i386, see bug URL in previous line
 
 --- a/test.c
 +++ b/test.c
-@@ -4221,7 +4221,13 @@
+@@ -4343,7 +4343,13 @@
    printf("http_parser v%u.%u.%u (0x%06lx)\n", major, minor, patch, version);
  
    printf("sizeof(http_parser) = %u\n", (unsigned int)sizeof(http_parser));

+ 4 - 0
debian/patches/series

@@ -1,4 +1,8 @@
 # cherry-picked commits. Keep in upstream's chronological order
+cherry-pick.v2.9.4-4-g805a0d1.fix-test-numbers.patch
+cherry-pick.v2.9.4-6-gd9275da.fix-wsign-compare-warning.patch
+cherry-pick.v2.9.4-7-g4b99e42.test-content-length-header-parsing.patch
+cherry-pick.v2.9.4-8-ge13b274.allow-content-length-and-transfer-encoding-chunked.patch
 cherry-pick.v2.9.4-9-g4f15b7d.fix-sizeof-http-parser-assert.patch
 
 # Debian-specific