CONNECT method should not have request body (#637)

* CONNECT method has no request body

### Motivation:

[rfc7231](https://tools.ietf.org/html/rfc7231#section-4.3.6) said:
> A payload within a `CONNECT` request message has no defined semantics;
   sending a payload body on a `CONNECT` request might cause some existing
   implementations to reject the request.

### Modifications:

Change `HTTPMethod.CONNECT.hasRequestBody` to returns `.no`.

### Result:

`HTTPRequestEncoder` does not generate chunked body for `CONNECT` method.

* Change `HTTPMethod.CONNECT.hasRequestBody` to returns `.unlikely`
This commit is contained in:
Norio Nomura 2018-10-30 14:54:52 +09:00 committed by Johannes Weiss
parent 6e6c68c1b2
commit 287d50c373
3 changed files with 21 additions and 2 deletions

View File

@ -959,9 +959,9 @@ public enum HTTPMethod: Equatable {
switch self {
case .HEAD, .DELETE, .TRACE:
return .no
case .POST, .PUT, .CONNECT, .PATCH:
case .POST, .PUT, .PATCH:
return .yes
case .GET, .OPTIONS:
case .GET, .CONNECT, .OPTIONS:
fallthrough
default:
return .unlikely

View File

@ -33,6 +33,7 @@ extension HTTPRequestEncoderTests {
("testNoTransferEncodingHeadersForHEAD", testNoTransferEncodingHeadersForHEAD),
("testNoChunkedEncodingForHTTP10", testNoChunkedEncodingForHTTP10),
("testBody", testBody),
("testCONNECT", testCONNECT),
]
}
}

View File

@ -116,6 +116,24 @@ class HTTPRequestEncoderTests: XCTestCase {
assertOutboundContainsOnly(channel, "")
}
func testCONNECT() throws {
let channel = EmbeddedChannel()
defer {
XCTAssertEqual(.some(false), try? channel.finish())
}
let uri = "server.example.com:80"
try channel.pipeline.add(handler: HTTPRequestEncoder()).wait()
var request = HTTPRequestHead(version: HTTPVersion(major: 1, minor:1), method: .CONNECT, uri: uri)
request.headers.add(name: "Host", value: uri)
XCTAssertNoThrow(try channel.writeOutbound(HTTPClientRequestPart.head(request)))
XCTAssertNoThrow(try channel.writeOutbound(HTTPClientRequestPart.end(nil)))
assertOutboundContainsOnly(channel, "CONNECT \(uri) HTTP/1.1\r\nHost: \(uri)\r\n\r\n")
assertOutboundContainsOnly(channel, "")
}
private func assertOutboundContainsOnly(_ channel: EmbeddedChannel, _ expected: String) {
if case .some(.byteBuffer(let buffer)) = channel.readOutbound() {
buffer.assertContainsOnly(expected)