update http_parser.c (#627)

Motivation:

There was an outstanding change in http_parser.c that we did not yet
have in our copy.

Modifications:

run the update http parser script and add changes as well as a test case
designed to hit the change.

Result:

ship the latest and greatest
This commit is contained in:
Johannes Weiss 2018-10-16 10:27:44 +01:00 committed by Cory Benfield
parent 8d7d4cb9ca
commit ed28803a78
3 changed files with 41 additions and 13 deletions

View File

@ -761,21 +761,16 @@ reexecute:
case s_start_res:
{
if (ch == CR || ch == LF)
break;
parser->flags = 0;
parser->content_length = ULLONG_MAX;
switch (ch) {
case 'H':
UPDATE_STATE(s_res_H);
break;
case CR:
case LF:
break;
default:
SET_ERRNO(HPE_INVALID_CONSTANT);
goto error;
if (ch == 'H') {
UPDATE_STATE(s_res_H);
} else {
SET_ERRNO(HPE_INVALID_CONSTANT);
goto error;
}
CALLBACK_NOTIFY(message_begin);
@ -2028,7 +2023,7 @@ reexecute:
}
}
/* Run callbacks for any marks that we have leftover after we ran our of
/* Run callbacks for any marks that we have leftover after we ran out of
* bytes. There should be at most one of these set, so it's OK to invoke
* them in series (unset marks will not result in callbacks).
*

View File

@ -39,6 +39,7 @@ extension HTTPDecoderTest {
("testDontDropExtraBytes", testDontDropExtraBytes),
("testExtraCRLF", testExtraCRLF),
("testSOURCEDoesntExplodeUs", testSOURCEDoesntExplodeUs),
("testExtraCarriageReturnBetweenSubsequentRequests", testExtraCarriageReturnBetweenSubsequentRequests),
]
}
}

View File

@ -364,4 +364,36 @@ class HTTPDecoderTest: XCTestCase {
XCTAssertNoThrow(try channel.finish())
}
func testExtraCarriageReturnBetweenSubsequentRequests() throws {
XCTAssertNoThrow(try channel.pipeline.add(handler: HTTPRequestDecoder()).wait())
// This is a simple HTTP/1.1 request with an extra \r between first and second message, designed to hit the code
// changed in https://github.com/nodejs/http-parser/pull/432 .
var buffer = channel.allocator.buffer(capacity: 64)
buffer.write(staticString: "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
buffer.write(staticString: "\r") // this is extra
buffer.write(staticString: "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
try channel.writeInbound(buffer)
let message: HTTPServerRequestPart? = self.channel.readInbound()
guard case .some(.head(let head)) = message else {
XCTFail("Invalid message: \(String(describing: message))")
return
}
XCTAssertEqual(head.method, .GET)
XCTAssertEqual(head.uri, "/")
XCTAssertEqual(head.version, .init(major: 1, minor: 1))
XCTAssertEqual(head.headers, HTTPHeaders([("Host", "example.com")]))
let secondMessage: HTTPServerRequestPart? = self.channel.readInbound()
guard case .some(.end(.none)) = secondMessage else {
XCTFail("Invalid second message: \(String(describing: secondMessage))")
return
}
XCTAssertNoThrow(try channel.finish())
}
}