swift-http-server: Use AsyncReader in RequestBody - #893
Conversation
Drain request body if it hasn't been consumed Return iterator to RenderState on errors
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## swift-http-server #893 +/- ##
====================================================
Coverage ? 89.39%
====================================================
Files ? 168
Lines ? 12781
Branches ? 0
====================================================
Hits ? 11426
Misses ? 1355
Partials ? 0 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
🟡 Changes recommended
Key streaming-related tests are currently disabled and HTTP/2 request draining behavior needs to be made robust to prevent regressions during the migration.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR migrates RequestBody from an AsyncSequence<ByteBuffer> model to an AsyncReader-based model (with UniqueArray<UInt8> buffers), updating server/channel handling and I/O utilities to match the new move-only reader semantics.
Changes:
- Replaces request-body streaming from
AsyncSequence<ByteBuffer>toRequestAsyncReader(UniqueArray<UInt8>buffers), makingRequestBodya reference type to support~Copyable. - Updates response writing and file I/O to accept
AsyncReaderinputs. - Updates benchmarks/tests for the new body representation; several streaming-related tests are temporarily disabled during the migration.
File summaries
| File | Description |
|---|---|
| Tests/HummingbirdTests/PersistTests.swift | Updates body collection/string decoding for UniqueArray<UInt8>. |
| Tests/HummingbirdTests/MiddlewareTests.swift | Temporarily disables response-writer middleware streaming tests. |
| Tests/HummingbirdTests/FileIOTests.swift | Switches FileIO write test to request.body.reader. |
| Tests/HummingbirdTests/ApplicationTests.swift | Migrates body APIs; temporarily disables streaming/bidirectional streaming tests. |
| Tests/HummingbirdRouterTests/MiddlewareTests.swift | Temporarily disables response-writer middleware streaming tests. |
| Tests/HummingbirdCoreTests/RequestBodyTests.swift | Updates request-body tests to construct via BaseRequestAsyncReader; disables inbound-close-handler tests. |
| Tests/HummingbirdCoreTests/HTTP1ChannelTests.swift | Updates expectations from readableBytes to count. |
| Tests/HummingbirdCoreTests/CoreTests.swift | Updates request/response body writing to new reader/buffer model; adds a delayed reader helper. |
| Sources/PerformanceTest/main.swift | Temporarily disables request-body echo path relying on async-sequence body. |
| Sources/HummingbirdTesting/RouterTestFramework.swift | Updates test request construction to use BaseRequestAsyncReader. |
| Sources/HummingbirdHTTP2/HTTP2StreamChannel.swift | Builds RequestBody via reader-state/reader; adjusts post-response inbound waiting logic. |
| Sources/HummingbirdCore/Utils/Disconnected.swift | Adds _Disconnected helper for moving non-Sendable values across isolation. |
| Sources/HummingbirdCore/Utils/AnyAsyncSequence.swift | Removes AnyAsyncSequence helper used by old request-body async-sequence model. |
| Sources/HummingbirdCore/Server/HTTP/HTTPChannelHandler.swift | Switches request construction to reader-backed bodies and drains bodies post-response for keep-alive. |
| Sources/HummingbirdCore/Response/ResponseBodyWriter.swift | Adds write(_ reader:) overload for AsyncReader of UniqueArray<UInt8>. |
| Sources/HummingbirdCore/Request/RequestBodyMergedWithUnderlyingRequestPartIterator.swift | Temporarily disabled pending RequestAsyncReader migration. |
| Sources/HummingbirdCore/Request/RequestBody+inboundClose.swift | Temporarily disabled pending RequestAsyncReader migration (consumeWithInboundCloseHandler). |
| Sources/HummingbirdCore/Request/RequestBody.swift | Replaces async-sequence backing with move-only reader backing; adds collect, pipe, drain, forEachBuffer. |
| Sources/HummingbirdCore/Request/RequestAsyncReader.swift | Introduces RequestAsyncReader, base channel-backed implementation, and collated reader. |
| Sources/HummingbirdCore/Request/Request.swift | Makes body a stored RequestBody and updates collectBody semantics/signature. |
| Sources/Hummingbird/Server/Request.swift | Removes unavailable legacy collate shim. |
| Sources/Hummingbird/Middleware/MetricsMiddleware.swift | Avoids capturing non-sendable request by copying method before closure. |
| Sources/Hummingbird/Files/FileIO.swift | Adds writeFile(reader:path:context:) overload for AsyncReader of UniqueArray<UInt8>. |
| Sources/Hummingbird/Exports.swift | Updates export of RequestBody to class instead of struct. |
| Sources/Hummingbird/Error/RequestAsyncReaderError+HTTPError.swift | Maps RequestAsyncReaderError to HTTP errors (e.g. payload too large). |
| Sources/Hummingbird/Codable/URLEncodedForm/URLEncodedForm+Request.swift | Updates request decoding to work from UniqueArray<UInt8> span. |
| Sources/Hummingbird/Codable/JSON/JSONCoding.swift | Updates JSON decoding to work from UniqueArray<UInt8> span. |
| Benchmarks/HummingbirdBenchmarks/RouterBenchmarks.swift | Updates benchmark request-body generation and body-size assertions. |
Review details
Suppressed comments (1)
Tests/HummingbirdTests/MiddlewareTests.swift:149
- Response-body-writer middleware tests are commented out, which removes coverage for
ResponseBodyWritercomposition during theRequestAsyncReadermigration. Replacing these with reader-based request streaming assertions would help ensure the newResponseBodyWriter.write(_ reader:)path works end-to-end.
/* TODO: Fixup for RequestAsyncReader
@Test func testMiddlewareResponseBodyWriter() async throws {
struct TransformWriter: ResponseBodyWriter {
var parentWriter: any ResponseBodyWriter
- Files reviewed: 28/28 changed files
- Comments generated: 6
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Added additional comments, fix up out of date comments
70b32cc to
f3c6173
Compare
Replace AsyncSequence of ByteBuffers in RequestBody with a AsyncReader. As the AsyncReader is
~Copyablethe easiest way to do this is make RequestBody a class.Also replace all functionality that returned a ByteBuffer to return a UniqueArray.
becomes
TODO:
consumeWithInboundCloseHandlerStreaming tests need a response writer, so will fix those later