flare_mlake · API · ws

flare.ws.server_h3

Server-side WebSocket over HTTP/3 (RFC 9220).

The HTTP/3 counterpart of :mod:flare.ws.server_h2: a client opens a WebSocket with an extended CONNECT (:protocol: websocket) request stream, the server answers 200 without ending the stream, and the WebSocket frames ride DATA frames on it both ways. The handler shape is the h2 sidecar's: edge-driven on_open / on_message / on_close over a per-tunnel :class:WsOverH3ServerStream, attached with :meth:flare.http.HttpServer.attach_ws_h3.

Structs

WsOverH3ServerStream

struct WsOverH3ServerStream

One WebSocket tunnel on an HTTP/3 stream. The RFC 6455 rules live in :class:flare.ws.protocol.WsProtocol; outbound frames are unmasked (RFC 6455 sec 5.3) and queued on the stream.

Implements Copyable, Movable

Fields
tunnel: Http3Tunnel
proto: WsProtocol
closed: Bool

__init__

def __init__(out self, tunnel: Http3Tunnel, var initial: List[UInt8])

send_frame

def send_frame(mut self, mut listener: QuicListener, frame: WsFrame)

Queue frame on the tunnel; a CLOSE frame ends it.

try_pull_frame

def try_pull_frame(mut self, mut listener: QuicListener) -> Optional[WsFrame]

The next complete message as one TEXT or BINARY frame, a CLOSE frame once the session has ended (its reply already sent), or None until more data arrives.

is_closed

def is_closed(self) -> Bool

close

def close(mut self, mut listener: QuicListener, code: UInt16 = UInt16(1000), reason: String = "")

Send a CLOSE frame; the tunnel ends once it is sent.

WsH3Hooks

struct WsH3Hooks

A boxed :trait:WsH3Handler and its thunks. Copies are non-owning; the owner runs destroy once.

Implements Copyable, Movable

Fields
addr: Int
open: def(Int, mut WsOverH3ServerStream, mut QuicListener) raises thin -> None
msg: def(Int, mut WsOverH3ServerStream, mut QuicListener, WsFrame) raises thin -> None
close: def(Int, mut WsOverH3ServerStream, mut QuicListener) raises thin -> None
destroy: def(Int) thin -> None
clone_box: def(Int) raises thin -> Int

__init__

def __init__(out self, addr: Int, open: def(Int, mut WsOverH3ServerStream, mut QuicListener) raises thin -> None, msg: def(Int, mut WsOverH3ServerStream, mut QuicListener, WsFrame) raises thin -> None, close: def(Int, mut WsOverH3ServerStream, mut QuicListener) raises thin -> None, destroy: def(Int) thin -> None, clone_box: def(Int) raises thin -> Int)

clone

def clone(self) -> Self

Hooks over a fresh boxed copy of the handler (one per worker); the caller destroys it.

Traits

WsH3Handler

Edge-driven handler for WebSocket-over-HTTP/3 tunnels, shared by every tunnel on the server like :trait:flare.ws.WsH2Handler.

Implements Copyable, Movable

on_open

def on_open(mut self, mut carrier: WsOverH3ServerStream, mut listener: QuicListener)

Called once when a tunnel is accepted.

on_message

def on_message(mut self, mut carrier: WsOverH3ServerStream, mut listener: QuicListener, frame: WsFrame)

Called per decoded client frame.

on_close

def on_close(mut self, mut carrier: WsOverH3ServerStream, mut listener: QuicListener)

Called once when the tunnel ends, whichever side ended it.

Functions

make_ws_h3_hooks

def make_ws_h3_hooks[W: WsH3Handler](var handler: W) -> WsH3Hooks

Box handler; the caller runs hooks.destroy(hooks.addr) once after the serve loop exits.

ws_h3_accept

def ws_h3_accept(hooks: WsH3Hooks, mut listener: QuicListener, mut tunnels: List[WsOverH3ServerStream])

Take every extended CONNECT stream that has arrived: a WebSocket one (:protocol: websocket, sec-websocket-version: 13, RFC 9220 sec 3 and RFC 8441 sec 5) becomes a tunnel and gets on_open; any other is refused (400 malformed, 501 another protocol) and its stream ends. Other requests are left for the HTTP handler.

ws_h3_dispatch

def ws_h3_dispatch(hooks: WsH3Hooks, mut listener: QuicListener, mut tunnels: List[WsOverH3ServerStream])

Hand each tunnel's arrived frames to on_message; a tunnel whose CLOSE went out, whose peer ended or reset it, or that sent a bad frame gets on_close and is ended and dropped.