Skip to content

Commit 2383b65

Browse files
committed
assume chunked on zero-length stream
1 parent 238c653 commit 2383b65

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

Sources/AsyncHTTPClient/RequestValidation.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ extension HTTPHeaders {
2727
}
2828

2929
self.remove(name: "Transfer-Encoding")
30-
self.remove(name: "Content-Length")
3130

3231
try self.validateFieldNames()
3332

3433
guard let body = body else {
34+
self.remove(name: "Content-Length")
3535
// if we don't have a body we might not need to send the Content-Length field
3636
// https://tools.ietf.org/html/rfc7230#section-3.3.2
3737
switch method {
@@ -60,11 +60,15 @@ extension HTTPHeaders {
6060
}
6161

6262
if encodings.isEmpty {
63-
guard let length = body.length else {
64-
throw HTTPClientError.contentLengthMissing
63+
if let length = body.length {
64+
self.remove(name: "Content-Length")
65+
contentLength = length
66+
} else if !self.contains(name: "Content-Length") {
67+
transferEncoding = "chunked"
6568
}
66-
contentLength = length
6769
} else {
70+
self.remove(name: "Content-Length")
71+
6872
transferEncoding = encodings.joined(separator: ", ")
6973
if !encodings.contains("chunked") {
7074
guard let length = body.length else {

Tests/AsyncHTTPClientTests/HTTPClientTests.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2005,4 +2005,35 @@ class HTTPClientTests: XCTestCase {
20052005

20062006
self.defaultClient = nil // so it doesn't get shut down again.
20072007
}
2008+
2009+
func testUploadStreamingNoLength() throws {
2010+
let server = NIOHTTP1TestServer(group: self.serverGroup)
2011+
let client = HTTPClient(eventLoopGroupProvider: .shared(self.clientGroup))
2012+
defer {
2013+
XCTAssertNoThrow(try client.syncShutdown())
2014+
XCTAssertNoThrow(try server.stop())
2015+
}
2016+
2017+
var request = try HTTPClient.Request(url: "http://localhost:\(server.serverPort)/")
2018+
request.body = .stream() { writer in
2019+
writer.write(.byteBuffer(ByteBuffer.of(string: "1234")))
2020+
}
2021+
2022+
let future = client.execute(request: request)
2023+
2024+
switch try server.readInbound() {
2025+
case .head(let head):
2026+
XCTAssertEqual(head.headers["transfer-encoding"], ["chunked"])
2027+
default:
2028+
XCTFail("Unexpected part")
2029+
}
2030+
2031+
XCTAssertNoThrow(try server.readInbound()) // .body
2032+
XCTAssertNoThrow(try server.readInbound()) // .end
2033+
2034+
XCTAssertNoThrow(try server.writeOutbound(.head(.init(version: .init(major: 1, minor: 1), status: .ok))))
2035+
XCTAssertNoThrow(try server.writeOutbound(.end(nil)))
2036+
2037+
XCTAssertNoThrow(try future.wait())
2038+
}
20082039
}

0 commit comments

Comments
 (0)