Full support for bidirectional streaming#879
Merged
fabianfett merged 14 commits intoswift-server:mainfrom Feb 3, 2026
Merged
Conversation
Lukasa
reviewed
Jan 23, 2026
| .executing(_, .finished, _), | ||
| .executing(_, .producing, _), | ||
| .executing(_, .paused, _): | ||
| preconditionFailure("Invalid state: \(self.state)") |
Collaborator
There was a problem hiding this comment.
We should think very hard about introducing more precondition failures in these state machines. Consider having this be an assert + throw.
| return .sendRequestEnd(writePromise) | ||
| case .sendRequestEnd(let writePromise, let finalAction): | ||
| guard case .inRequest(_, close: let close) = self else { | ||
| fatalError("Invalid state: \(self)") |
Collaborator
There was a problem hiding this comment.
Same note here about these crashes: unless we can write a comment explaining why this is impossible and a code reviewer can check it, better to do assert + throw.
| } | ||
|
|
||
| private func requestBodyStreamSent0() { | ||
|
|
Collaborator
There was a problem hiding this comment.
Is this intentionally empty?
glbrntt
reviewed
Feb 3, 2026
Sources/AsyncHTTPClient/ConnectionPool/HTTP1/HTTP1ClientChannelHandler.swift
Show resolved
Hide resolved
Sources/AsyncHTTPClient/ConnectionPool/HTTP2/HTTP2ClientRequestHandler.swift
Show resolved
Hide resolved
glbrntt
reviewed
Feb 3, 2026
Sources/AsyncHTTPClient/ConnectionPool/HTTP1/HTTP1ClientChannelHandler.swift
Outdated
Show resolved
Hide resolved
…lHandler.swift Co-authored-by: George Barnett <gbarnett@apple.com>
glbrntt
approved these changes
Feb 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is foundational work needed to properly support HTTP trailers and scenarios where the server sends a complete response before the client finishes uploading (e.g., early rejection, 100-continue flows, or bidirectional streaming protocols).
Changes
State Machine Improvements
Added
endForwardedstate toTransaction.StateMachine.RequestStreamStateRenamed
succeedRequest→forwardResponseEndin bothHTTPRequestStateMachine.ActionandHTTP1ConnectionStateMachine.ActionProtocol Changes
requestBodyStreamSent()toHTTPExecutableRequestprotocolTransactionandRequestBagRequest State Machine Updates
Updated
FinalSuccessfulRequestAction.sendRequestEnd(EventLoopPromise<Void>?)to simpler.requestDone.nonecase for when response completes but request is still in-flightsendRequestEndaction now includesFinalSuccessfulRequestActionChannel Handler Updates
HTTP1ClientChannelHandler
sendRequestEndnow properly handles scenarios where response has already completedHTTP2ClientRequestHandler
sendRequestEndsignature.requestDone)RequestBag State Machine
Added
endReceivedstate toResponseStreamStateUpdated
FinishAction.forwardStreamFinishedAndSucceedTaskfor the case where both streams complete simultaneouslyError Handling
Transaction.StateMachinecancelExecutoraction to the fail pathfailRequestStreamContinuationfor proper cleanupTechnical Details
The Problem
Previously, when a server sent a complete response before the client finished uploading the request body, AHC would:
This made it impossible to implement proper bidirectional streaming or handle scenarios like:
The Solution
The new state machine properly tracks four completion states:
endForwarded/endReceivedstatesThe key insight is the
endForwardedstate, which represents "we've given all request data to the channel, but it hasn't been written to the network yet". This allows us to:Future Work
This PR lays the groundwork for: