From 6d67727e52848be62ce6bd0a533274fd3810671e Mon Sep 17 00:00:00 2001 From: Gus Cairo Date: Fri, 3 Jul 2026 14:57:22 +0100 Subject: [PATCH 1/3] Depend on swift-http-api-proposal 0.2.0 --- Package.swift | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Package.swift b/Package.swift index dee08dc..edc64c4 100644 --- a/Package.swift +++ b/Package.swift @@ -48,10 +48,7 @@ let package = Package( .default(enabledTraits: ["Configuration"]), ], dependencies: [ - .package( - url: "https://github.com/apple/swift-http-api-proposal.git", - revision: "c12fdd4c48953a691b1ce52357101e844e5f0887" - ), + .package(url: "https://github.com/apple/swift-http-api-proposal.git", from: "0.2.0"), .package(url: "https://github.com/apple/swift-distributed-tracing.git", from: "1.4.1"), .package(url: "https://github.com/apple/swift-certificates.git", from: "1.19.1"), .package(url: "https://github.com/apple/swift-log.git", from: "1.13.2"), From d9c184cf33c0a2a76c75c0ac027dcd03139c2ae1 Mon Sep 17 00:00:00 2001 From: Gus Cairo Date: Fri, 3 Jul 2026 16:30:02 +0100 Subject: [PATCH 2/3] Fix broken tests because of updated AsyncStreaming APIs --- .../HTTPKeepAliveHandlerTests.swift | 10 +++++-- .../NIOHTTPServerTests/HTTPServerTests.swift | 8 +++-- .../NIOHTTPServerReaderTests.swift | 20 ++++++++----- .../NIOHTTPServerTests.swift | 29 ++++++++++--------- 4 files changed, 40 insertions(+), 27 deletions(-) diff --git a/Tests/NIOHTTPServerTests/HTTPKeepAliveHandlerTests.swift b/Tests/NIOHTTPServerTests/HTTPKeepAliveHandlerTests.swift index 077f0c6..c7d324a 100644 --- a/Tests/NIOHTTPServerTests/HTTPKeepAliveHandlerTests.swift +++ b/Tests/NIOHTTPServerTests/HTTPKeepAliveHandlerTests.swift @@ -200,7 +200,9 @@ struct HTTPKeepAliveHandlerTests { } // Read the full request body (until .end). - let _ = try await reader.collect(upTo: 1024) { _ in } + var requestBody = UniqueArray() + requestBody.reserveCapacity(1024) + _ = try await reader.collect(into: &requestBody) // Write the final response. var buffer = UniqueArray(copying: "hello".utf8) @@ -407,9 +409,11 @@ struct HTTPKeepAliveHandlerTests { _ = await canFinishIterator.next() // Drain the request body + end and then write the response body + end. - _ = try await reader.collect(upTo: 1024) { _ in } + var requestBody = UniqueArray() + requestBody.reserveCapacity(1024) + _ = try await reader.collect(into: &requestBody) var buffer = UniqueArray(copying: "hello".utf8) - try await writer.finish(buffer: &buffer) + try await writer.finish(buffer: &buffer, finalElement: nil) }, body: { serverAddress in let client = try await ClientBootstrap(group: .singletonMultiThreadedEventLoopGroup) diff --git a/Tests/NIOHTTPServerTests/HTTPServerTests.swift b/Tests/NIOHTTPServerTests/HTTPServerTests.swift index 322af35..1939375 100644 --- a/Tests/NIOHTTPServerTests/HTTPServerTests.swift +++ b/Tests/NIOHTTPServerTests/HTTPServerTests.swift @@ -34,16 +34,18 @@ struct HTTPServerTests { try await withThrowingTaskGroup { group in group.addTask { try await server.serve { request, context, reader, responseSender in - _ = try await reader.collect(upTo: 100) { _ in } + var requestBody = UniqueArray() + requestBody.reserveCapacity(100) + _ = try await reader.collect(into: &requestBody) // Uncommenting this would cause a "reader consumed more than once" error. - // _ = try await reader.collect(upTo: 100) { _ in } + // _ = try await reader.collect(into: &requestBody) let responseWriter = try await responseSender.send(HTTPResponse(status: .ok)) // Uncommenting this would cause a "responseSender consumed more than once" error. // let responseWriter2 = try await responseSender.send(HTTPResponse(status: .ok)) var buffer = UniqueArray(copying: [1, 2]) - try await responseWriter.finish(buffer: &buffer) + try await responseWriter.finish(buffer: &buffer, finalElement: nil) // Uncommenting this would cause a "responseWriter consumed more than once" error. // try await responseWriter.finish( diff --git a/Tests/NIOHTTPServerTests/NIOHTTPServerReaderTests.swift b/Tests/NIOHTTPServerTests/NIOHTTPServerReaderTests.swift index 30a2b0f..5d871e3 100644 --- a/Tests/NIOHTTPServerTests/NIOHTTPServerReaderTests.swift +++ b/Tests/NIOHTTPServerTests/NIOHTTPServerReaderTests.swift @@ -181,15 +181,21 @@ struct NIOHTTPServerReaderTests { readerState: .init(iterator: stream.makeAsyncIterator()) ) + var buffer = UniqueArray() + buffer.reserveCapacity(9) do { - _ = try await requestReader.collect(upTo: 9) { _ in } - } catch let eitherEitherError - as EitherError, Never> - { + _ = try await requestReader.collect(exactlyInto: &buffer) + } catch let error as EitherError< + any Error, + EitherError + > { do { - try eitherEitherError.unwrap() - } catch let eitherError as EitherError { - try eitherError.unwrap() + try error.unwrap() + } catch let inner as EitherError< + AsyncReaderLeftOverElementsError, + AsyncReaderInsufficientElementsError + > { + try inner.unwrap() } } } diff --git a/Tests/NIOHTTPServerTests/NIOHTTPServerTests.swift b/Tests/NIOHTTPServerTests/NIOHTTPServerTests.swift index 2f01ff5..47a03fe 100644 --- a/Tests/NIOHTTPServerTests/NIOHTTPServerTests.swift +++ b/Tests/NIOHTTPServerTests/NIOHTTPServerTests.swift @@ -78,11 +78,11 @@ struct NIOHTTPServerTests { serverHandler: HTTPServerClosureRequestHandler { request, requestContext, reader, responseWriter in #expect(request == Self.makeRequest(method: .post, scheme: "http", for: .http1_1)) - let (buffer, finalElement) = try await reader.collect(upTo: Self.bodyData.readableBytes + 1) { body in - var buffer = ByteBuffer() - buffer.writeBytes(body.span.bytes) - return buffer - } + var collected = UniqueArray() + collected.reserveCapacity(Self.bodyData.readableBytes + 1) + let finalElement = try await reader.collect(into: &collected) + var buffer = ByteBuffer() + buffer.writeBytes(collected.span.bytes) #expect(buffer == Self.bodyData) #expect(finalElement == Self.trailer) @@ -146,12 +146,11 @@ struct NIOHTTPServerTests { let peerChain = try #require(try await NIOHTTPServer.connectionContext.peerCertificateChain) #expect(Array(peerChain) == [clientChain.leaf]) - let (buffer, finalElement) = try await reader.collect(upTo: Self.bodyData.readableBytes + 1) { - body in - var buffer = ByteBuffer() - buffer.writeBytes(body.span.bytes) - return buffer - } + var collected = UniqueArray() + collected.reserveCapacity(Self.bodyData.readableBytes + 1) + let finalElement = try await reader.collect(into: &collected) + var buffer = ByteBuffer() + buffer.writeBytes(collected.span.bytes) #expect(buffer == Self.bodyData) #expect(finalElement == Self.trailer) @@ -982,9 +981,11 @@ extension NIOHTTPServerTests { sender: consuming NIOHTTPServer.ResponseSender ) async throws { var buffer = UniqueArray() - let (_, trailer) = try await reader.collect(upTo: limit) { inputSpan in - buffer.append(copying: inputSpan) - } + // Reserve one extra byte beyond the limit: `collect(into:)` stops as soon as the buffer's + // free capacity is exhausted, so an exact fit would drop the trailing fields delivered in + // the terminal chunk. + buffer.reserveCapacity(limit + 1) + let trailer = try await reader.collect(into: &buffer) try await sender.sendAndFinish(.init(status: .ok), buffer: &buffer, trailer: trailer) } } From 7bb612509eb6c885251b87735274846f917a75cd Mon Sep 17 00:00:00 2001 From: Gus Cairo Date: Fri, 3 Jul 2026 16:34:39 +0100 Subject: [PATCH 3/3] Format --- .../NIOHTTPServerReaderTests.swift | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Tests/NIOHTTPServerTests/NIOHTTPServerReaderTests.swift b/Tests/NIOHTTPServerTests/NIOHTTPServerReaderTests.swift index 5d871e3..2546664 100644 --- a/Tests/NIOHTTPServerTests/NIOHTTPServerReaderTests.swift +++ b/Tests/NIOHTTPServerTests/NIOHTTPServerReaderTests.swift @@ -185,16 +185,20 @@ struct NIOHTTPServerReaderTests { buffer.reserveCapacity(9) do { _ = try await requestReader.collect(exactlyInto: &buffer) - } catch let error as EitherError< - any Error, - EitherError - > { + } catch let error + as EitherError< + any Error, + EitherError + > + { do { try error.unwrap() - } catch let inner as EitherError< - AsyncReaderLeftOverElementsError, - AsyncReaderInsufficientElementsError - > { + } catch let inner + as EitherError< + AsyncReaderLeftOverElementsError, + AsyncReaderInsufficientElementsError + > + { try inner.unwrap() } }