WebSocket
Octopus is a full WebSocket proxy. It performs the RFC 6455 upgrade handshake with the client, opens a WebSocket connection to the upstream, and then forwards frames in both directions until either side closes.
Detection01
A request is treated as a WebSocket upgrade when it has both:
Upgrade: websocket, anda
Connectionheader containing anupgradetoken (case-insensitive, comma-tolerant).
This check runs first, before the body is buffered, so hyper's upgrade machinery stays intact. Only WebSocket protocol version 13 is accepted during the handshake; other versions are rejected.
How it is handled02
Route match. The upstream is selected by the normal router from the request host, method, and path. No matching route means the upgrade is refused.
Connect upstream first. The gateway dials the upstream WebSocket before replying
to the client, with a connect timeout (default 10s). If the upstream is unreachable the
client gets a 502 and no upgrade happens. The upstream URL is derived from the
upstream's base URL with the scheme rewritten to ws:// / wss://, applying the route's
strip_prefix / add_prefix.
Forward headers. A curated set of headers is forwarded to the upstream:
X-Forwarded-For, X-Real-IP, X-Forwarded-Proto (set to ws), Origin, Cookie,
Authorization, and Sec-WebSocket-Protocol.
Complete the handshake. The gateway returns 101 Switching Protocols with the
computed Sec-WebSocket-Accept, echoing the client's Sec-WebSocket-Protocol if present.
Proxy frames. A background task runs a bidirectional loop, forwarding messages each way. It sends keepalive pings on an interval, answers incoming pings with pongs, and performs the RFC 6455 close handshake (forwarding the close frame and waiting, up to a timeout, for the peer's close reply).
Example route03
A WebSocket endpoint is an ordinary route pointed at an upstream that accepts WebSocket connections:
upstreams:
- name: ws-service
instances:
- id: ws-1
host: 127.0.0.1
port: 9001
routes:
- path: /ws
upstream: ws-serviceThe same route can also carry plain HTTP requests — the gateway only treats a request as a WebSocket when the upgrade headers are present. See Routes and Routing.
Size and timeout limits04
WebSocket frame/message size limits and timeouts come from built-in defaults, not from
route or gateway configuration. There is no max_message_size (or similar) field on a
route that the WebSocket path reads. The compiled-in defaults are:
| Limit | Default |
| Max frame size | 16 MB |
| Max message size | 64 MB |
| Keepalive ping interval | 30s |
| Close handshake timeout | 5s |
| Upstream connect timeout | 10s |
Do not document or rely on per-route WebSocket tuning fields — the handler constructs its config from defaults and these values are not currently configurable from YAML.
Limitations05
WebSocket tuning (sizes, timeouts, ping interval) is not configurable from configuration; the defaults above are compiled in.
Per-message-deflate / compression extensions are not negotiated by the gateway.
The upstream URL scheme is derived by rewriting the upstream base URL to
ws/wss; the upstream must accept a WebSocket upgrade at the rewritten path.