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"), 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..2546664 100644 --- a/Tests/NIOHTTPServerTests/NIOHTTPServerReaderTests.swift +++ b/Tests/NIOHTTPServerTests/NIOHTTPServerReaderTests.swift @@ -181,15 +181,25 @@ 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) } }