Skip to content

Commit 31d7652

Browse files
authored
fix: content-length middleware should not error on event streams (#608)
1 parent e0b4f25 commit 31d7652

File tree

2 files changed

+23
-7
lines changed

2 files changed

+23
-7
lines changed

Sources/ClientRuntime/Networking/Http/Middlewares/ContentLengthMiddleware.swift

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,17 @@ public struct ContentLengthMiddleware<OperationStackOutput: HttpResponseBinding>
66

77
private let contentLengthHeaderName = "Content-Length"
88

9-
private var requiresLength: Bool = false
9+
private var requiresLength: Bool?
1010

11-
private var unsignedPayload: Bool = false
11+
private var unsignedPayload: Bool?
1212

13-
public init(requiresLength: Bool = false, unsignedPayload: Bool = false) {
13+
/// Creates a new `ContentLengthMiddleware` with the supplied parameters
14+
/// - Parameters:
15+
/// - requiresLength: Trait requires the length of a blob stream to be known.
16+
/// When the request body is not a streaming blob, `nil` should be passed. Defaults to `nil`.
17+
/// - unsignedPayload: Trait signifies that the length of a stream in payload does not need to be known.
18+
/// When the request body is not a streaming blob, `nil` should be passed. Defaults to `nil`.
19+
public init(requiresLength: Bool? = nil, unsignedPayload: Bool? = nil) {
1420
self.requiresLength = requiresLength
1521
self.unsignedPayload = unsignedPayload
1622
}
@@ -29,13 +35,16 @@ public struct ContentLengthMiddleware<OperationStackOutput: HttpResponseBinding>
2935
case .stream(let stream):
3036
if let length = stream.length {
3137
input.headers.update(name: "Content-Length", value: String(length))
32-
} else if !requiresLength && unsignedPayload {
33-
// only for HTTP/1.1 requests, will be removed in all HTTP/2 requests
38+
} else if (requiresLength == false && unsignedPayload == true) ||
39+
(requiresLength == nil && unsignedPayload == nil) {
40+
// Transfer-Encoding can be sent on all Event Streams where length cannot be determined
41+
// or on blob Data Streams where requiresLength is true and unsignedPayload is false
42+
// Only for HTTP/1.1 requests, will be removed in all HTTP/2 requests
3443
input.headers.update(name: "Transfer-Encoding", value: "Chunked")
3544
} else {
3645
let operation = context.attributes.get(key: AttributeKey<String>(name: "Operation"))
3746
?? "Error getting operation name"
38-
let errorMessage = unsignedPayload ?
47+
let errorMessage = (unsignedPayload ?? false) ?
3948
"Missing content-length for operation: \(operation)" :
4049
"Missing content-length for SigV4 signing on operation: \(operation)"
4150
throw StreamError.notSupported(errorMessage)

Tests/ClientRuntimeTests/NetworkingTests/ContentLengthMiddlewareTests.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ class ContentLengthMiddlewareTests: XCTestCase {
2727
try await AssertHeadersArePresent(expectedHeaders: ["Transfer-Encoding": "Chunked"])
2828
}
2929

30+
func testTransferEncodingChunkedSetWithNilTraits() async throws {
31+
// default constructor
32+
addContentLengthMiddlewareWith(requiresLength: nil, unsignedPayload: nil)
33+
forceEmptyStream()
34+
try await AssertHeadersArePresent(expectedHeaders: ["Transfer-Encoding": "Chunked"])
35+
}
36+
3037
func testContentLengthSetWhenStreamLengthAvailableAndRequiresLengthSet() async throws {
3138
addContentLengthMiddlewareWith(requiresLength: true, unsignedPayload: false)
3239
try await AssertHeadersArePresent(expectedHeaders: ["Content-Length": "0"])
@@ -54,7 +61,7 @@ class ContentLengthMiddlewareTests: XCTestCase {
5461
}
5562
}
5663

57-
private func addContentLengthMiddlewareWith(requiresLength: Bool, unsignedPayload: Bool) {
64+
private func addContentLengthMiddlewareWith(requiresLength: Bool?, unsignedPayload: Bool?) {
5865
stack.finalizeStep.intercept(
5966
position: .before,
6067
middleware: ContentLengthMiddleware(requiresLength: requiresLength, unsignedPayload: unsignedPayload)

0 commit comments

Comments
 (0)