Replies: 1 comment
|
Related option worth noting: Not proposing this as the chosen path, just flagging it as prior art since it's directly relevant to the "duplicating infrastructure" concern above.
It's essentially the "duplicated infrastructure" this proposal is trying to avoid writing from scratch — except already written and maintained upstream by Vapor. If Trade-offs that would need weighing, not glossed over:
Leaving this here as a documented alternative for whoever revisits this, not as a recommendation over the upstream |
Uh oh!
There was an error while loading. Please reload this page.
Overview
Does WebSocket fit RequestDL? The handshake half does — it's an HTTP/1.1 Upgrade request that can reuse RequestDL's existing declarative
BaseURL/Headers/session/TLS/proxy configuration. The connection-lifecycle half (a long-lived, bidirectional message stream) doesn't fit the existingProperty/RequestTask.result()one-shot request/response model at all, and — more importantly — can't be built cleanly without duplicating infrastructureAsyncHTTPClientalready owns.Status: 🚫 blocked upstream
Same shape of gap as #191 (Network Capabilities) and the SOCKS Authentication proposal, confirmed directly rather than assumed:
AsyncHTTPClienthas zero WebSocket support today — nothing in its source references it.swift-nio's ownNIOWebSocketClient/NIOWebSocketServeraren't reusable libraries — they're.executableTargetdemo programs inswift-nio's own repo, not exposed as library products. Only the low-levelNIOWebSocketframe codec is actually importable.AsyncHTTPClient'sHTTPConnectionPool+Factory.swift. A downstream package (RequestDL or otherwise) attempting this would have to open an independent NIO connection and re-implement that whole configuration surface to get parity — not "building on top ofAsyncHTTPClient," duplicating it.HTTPClient.execute(request:delegate:)'s delegate model has no channel-hijack hook — no supported way to say "repurpose this connection's channel for something else" once a response starts.Proposed path forward
A design doc has been drafted (living in this repo, not yet filed against the upstream project):
async-http-client/WEBSOCKET-PROPOSAL.md. Summary: a newHTTPClient.executeWebSocketUpgrade(request:configuration:) async throws -> WebSocketAPI, reusing the exact same pooled-connection path ordinary requests already go through, swapping the channel's pipeline from HTTP/1 framing toNIOWebSocketframing after a101 Switching Protocolsresponse — implemented inside the sameHTTPConnectionPool+Factory.swiftbootstrap construction that already handles TLS/proxy/SOCKS today. Scoped to HTTP/1.1 only (not RFC 8441's HTTP/2 WebSocket, notpermessage-deflatecompression) for v1.RequestDL-side plan, once it lands
Internals.Clientcalls the new upgrade API on the same pooledHTTPClientinstance it already manages viaInternals.ClientManager— no separate connection-management path needed. A new publicWebSocketTask, built from existingPropertytypes the same declarative way every other task is, wraps the result. This is a genuinely different task shape fromDataTask/DownloadTask/UploadTask— an open, bidirectional message stream rather than a one-shot resolve-and-return — but RequestDL already has precedent for tasks with different result shapes (UploadTask's step-basedAsyncResponsevs.DataTask's simpleTaskResult).Out of scope
Milestone: TBD — depends on external project timeline outside this repo's control.
All reactions