lilydocs
HTTP APIWebSocketConsumer
Connections3 min read

Upgrade policy

Distinguish admission order before HTTP 101 from WebSocket policies that begin after connection establishment.

A client first sends an HTTP Upgrade request to open a WebSocket connection. Lily validates it against the application's endpoint, namespace, Origin, and subprotocol policies. Message actions have not started at this stage.

Admission order#

Connection flow
Capacity, TLS and handshake budget
  → exact endpoint, header validation, namespace
  → Origin ve subprotocol
  → global handshake middleware → controller handshake middleware
  → varsa tek global identity middleware
  → handshake scope cleanup
  → HTTP 101
  → connection admit → register connection → opened → connected
  → message loop

Middleware cannot retroactively accept a failed transport or Origin check. The identity result is not published to the connection until the handshake scope has been cleaned up either.

Endpoint and namespace#

The default endpoint is /ws. ws://127.0.0.1:8081/ws?namespace=hello requires both the exact path and a registered namespace. The path is not an HTTP controller route; one Upgrade endpoint carries many namespaces.

Namespace matching is case-sensitive. Declaring a namespace in the first message does not replace a namespace missing during Upgrade. Using the controller name as the URL path is not equivalent either. See controllers for selection rules.

Headers and request information#

Handshake middleware reads normalized information through exchange.request(). Access a custom header with:

Reading during the handshake
let authorization = exchange.request().headers()
    .get_custom_header("authorization");
let secure = exchange.request().is_secure();

The transport validates header size, count, and duplicate fields. Do not transfer HTTP examples here assuming there is a general-purpose query extractor API. Selecting namespace through the query is part of the public transport contract.

headers().get_protocols() returns the client's offered list, while negotiated_subprotocol() shows the selected value. Use the proxy policy for a trusted client IP; do not use a raw forwarded header directly as a rate-limit key.

Rejection boundary#

Before 101, WsHandshakeRejection can produce an HTTP status, bounded body, and permitted response headers. After 101, a new HTTP 401 or 429 cannot be returned; connection/message policy chooses a WebSocket error or Close.

If you place authentication inside connected, the HTTP rejection phase has already passed. Use identity middleware for pre-101 verification and connection middleware for post-connection observation. Global and controller handshake middleware run sequentially within their own phase's time limit.

Sources for this page v0.1.0

This guide is based on the reviewed framework commit.

QUICK START
Documentation
Source code