Skip to content

Native WebSocket support for k8s http-proxy routes#758

Merged
prathamesh0 merged 12 commits into
mainfrom
websocket-mux
Jun 10, 2026
Merged

Native WebSocket support for k8s http-proxy routes#758
prathamesh0 merged 12 commits into
mainfrom
websocket-mux

Conversation

@prathamesh0

Copy link
Copy Markdown
Collaborator
  • websocket: true on an http-proxy route now works: same public URL serves HTTP and WebSocket, split by Upgrade header — the Solana RPC convention (wss:// at the same address as https://)
  • Since the k8s Ingress API can't express header-based routing, SO generates a small Caddy mux ({deployment}-ws-mux) per deployment that needs it, and points the Ingress at it. Image overridable via a ws-mux-image spec key
  • Conflicting routes (two plain routes on one host+path) now fail deploy create loudly instead of silently emitting duplicate Ingress paths
  • Ingresses without TLS (kind) get disable-ssl-redirect — previously every HTTP route 308'd into a cert-less HTTPS endpoint
  • Verified end-to-end on kind, over both HTTP and TLS: 101 handshake + echo round-trip through controller → mux, lowercase-header clients, controller restarts, redeploys, and down cleanup. No protocol forcing needed — this replaces the in-memory admin-API patch that broke on every Caddy restart
  • 27 new unit tests; fixture stack (test-websocket) included for re-verification

prathamesh0 and others added 12 commits June 10, 2026 08:04
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… ingress path

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Without TLS (kind), the controller 308-redirects every HTTP route to a
cert-less HTTPS endpoint that fails the handshake — discovered while
verifying websocket passthrough on kind.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Caddy's plain header matcher is case-sensitive; clients like Node's
native WebSocket send lowercase tokens and would silently fall through
to the HTTP backend. Verified against real Caddy: lowercase handshake
now gets 101.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
caddy run never re-reads the config, so a ConfigMap update alone left
the running mux stale across redeploys. A content hash annotation on
the pod template forces a new ReplicaSet when the rendered config
changes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
disable-ssl-redirect keyed on 'not use_tls', which only means 'is kind' —
a kind cluster with acme-email set obtains real certs via Caddy ACME and
the redirect is load-bearing there. Gate the annotation on the absence of
acme-email so only cert-less local clusters lose the redirect.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@prathamesh0 prathamesh0 merged commit 3c6d2f7 into main Jun 10, 2026
7 checks passed
@prathamesh0 prathamesh0 deleted the websocket-mux branch June 10, 2026 09:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant