Skip to main content

Module subscription_wire

Module subscription_wire 

Expand description

What every subscription session binding shares (docs/design/subscriptions-websocket.md §6.3, §6.4, §6.6): the frames, admission (Init, authentication, refusal close codes), which browser origins may open a session, the per-principal session count, and the rate-limit seam that charges each subscription open. WebTransport (cratestack-webtransport) and WebSocket (cratestack-websocket) only move these frames over their own transport.

Modules§

admission
Admitting a subscription session, whatever carries it (docs/design/subscriptions-websocket.md §6.3): the first frame must be Init, its headers stand in for the handshake’s when present, and a refusal’s close code follows the error’s status.
frame
The frames a WebTransport subscription session carries (docs/design/subscriptions-websocket.md §6.4, §6a.2).
origin
Which browser origins may open a session (design §6.3, “Origin”).
principal
Who a session belongs to: the key re-authentication must preserve (design §6.3, “Expiry and refresh”) and the key sessions are counted under (§6.6, “Sockets per principal”).
rate_limit
Rate-limiting subscription opens on the session bindings (docs/design/subscriptions-websocket.md §6.7): the seam WebSocket and WebTransport call, implemented by cratestack-axum’s SubscriptionRateLimiter over OpExecutor::admit_rate_limit. One token per subscription Request; the session itself is not charged.

Structs§

ClientFrame
Anything a client sends.
Empty
An empty object ({}), the payload of ready and end.
Handshake
What the handshake (WebTransport CONNECT, WebSocket upgrade) carried that authentication needs later.
InitBody
Init body: the credentials a browser cannot put on the CONNECT request. Empty for a client that authenticated with CONNECT headers.
ServerFrame
Anything the server sends. Exactly one of the optional fields is set.
SessionCharger
One session’s standing answer to “who pays”: built once per session and cloned into every subscription task. With no limiter it admits everything.
SessionRegistry
Open sessions per key, shared by every session of one server. A poisoned lock is recovered rather than propagated: the guarded state is a counter no panic can leave half-updated, and propagating would turn one panicked task into a refusal of every later session.
SessionSlot
One admitted session. Dropping it frees the slot, however the session ended.
SubscriptionCharge
What a binding knows about one subscription open.

Enums§

ClientMessage
A client frame, classified.
OriginPolicy
Which Origins are accepted.
SubscriptionRefusal
Why an open was refused before Ready.

Traits§

SubscriptionRateLimit
Charges one subscription open. Debug so binding configs keep deriving it.

Functions§

authenticate_session
Runs the app’s AuthProvider over the handshake request. Init headers, when present, stand in for the handshake’s: that is how a browser, which cannot set headers on new WebTransport(url) or new WebSocket(url), presents credentials. A native client sends them on the handshake and an empty Init.
default_principal_key
The default principal key (PrincipalKeyFn in a binding config): the principal’s actor.id, else the auth identity’s id, else its sub. A context with none of them is anonymous.
init_headers
The first frame must be Init: its headers, else None.
refusal_close_code
The close code a refusal ends the session with, from the error’s HTTP status: 401 → 4401 and 403 → 4403, as on REST; a malformed Init → 4400; and a provider that could not decide (5xx: a key server down) → 4500, which is not a verdict on the credentials — a client must retry later rather than sign the user out.
session_key
What a session is counted under: the principal, or the remote IP for an anonymous caller, so one address cannot hold unlimited anonymous sessions either.