WebSocket upgrade to an https upstream returns 501 #45
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Spec:
obsidian/Personal/Projects/edge-router/specs/2026-10-22-websocket-to-https-upstream-design.mdA WebSocket upgrade to a service with
target_scheme = "https"returns 501. The refusal is currently correct, not a bug:proxy_websocketopens a rawTcpStreamand hands it to hyper, because after the 101 it is a byte tunnel with nothing HTTP-shaped left to route — so there is no TLS layer on that path, and connecting plaintext to a TLS port would be worse than failing.The fix is a
tokio_rustlsclient layer beneath the existing upgrade logic, which is already generic over the stream type.The part worth care is not the TLS wrapping (a dozen lines) but that
upstream::apply_ca_pinning— the single source of truth for what an https upstream trusts, deliberately shared by the proxy client and the health probe — takes areqwest::ClientBuilder, whiletokio_rustlsneeds arustls::ClientConfig. Two independent CA-loading paths would drift, and the result would be the WebSocket route trusting public roots while the proxy route is pinned to an internal CA: a silent, partial downgrade of the same class as #38. So the decision gets factored out of the application, with both shapes as thin adapters over one function.Blocks Roku's browser TLS on 2443.
Scheduled for the same release as the per-name ACME work (
feat/per-name-acme-httpreq) by agreement, though it is an independent change.