flare_mlake · API · ws

flare.ws.frame

WebSocket frame codec (RFC 6455 §5).

Frame wire format (§5.2):

0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+-+-+-+-+-------+-+-------------+-------------------------------+ |F|R|R|R| opcode|M| Payload len | Extended payload length | |I|S|S|S| (4) |A| (7) | (16/64) | |N|V|V|V| |S| | (if payload len==126/127) | | |1|2|3| |K| | | +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - -+ | Extended payload length continued, if payload len == 127 |

                              • -+-------------------------------+ | |Masking-key, if MASK set to 1 | +-------------------------------+-------------------------------+ | Masking-key (continued) | Payload Data | +-------------------------------- - - - - - - - - - - - - - - -+ : Payload Data continued ... : +---------------------------------------------------------------+

Masking (§5.3): Every client→server frame payload byte is XOR'd with a rotating 4-byte masking key. Server→client frames MUST NOT be masked. This implementation uses SIMD-32 masking for payloads ≥ 64 bytes.

Structs

WsOpcode

struct WsOpcode

WebSocket opcode byte constants (RFC 6455 §5.2).

Implements Movable

comptime CONTINUATION = UInt8(0)
comptime TEXT = UInt8(1)
comptime BINARY = UInt8(2)
comptime CLOSE = UInt8(8)
comptime PING = UInt8(9)
comptime PONG = UInt8(10)

WsCloseCode

struct WsCloseCode

WebSocket close status code constants (RFC 6455 §7.4.1).

Implements Movable

comptime NORMAL = UInt16(1000)

Clean, normal closure.

comptime GOING_AWAY = UInt16(1001)

Endpoint going away (e.g. server restart).

comptime PROTOCOL_ERROR = UInt16(1002)

Protocol violation.

comptime UNSUPPORTED_DATA = UInt16(1003)

Received unsupported data type.

comptime NO_STATUS = UInt16(1005)

Reserved — must not be sent; used when code is absent in Close frame.

comptime ABNORMAL = UInt16(1006)

Reserved — must not be sent; used when connection drops without Close.

comptime INVALID_PAYLOAD = UInt16(1007)

Text frame contained invalid UTF-8.

comptime POLICY_VIOLATION = UInt16(1008)

Message violates server policy.

comptime MESSAGE_TOO_BIG = UInt16(1009)

Message exceeded configured size limit.

comptime INTERNAL_ERROR = UInt16(1011)

Server encountered an internal error.

WsProtocolError

struct WsProtocolError

Raised when an incoming frame violates RFC 6455.

Implements Copyable, Movable, Writable

Fields
message: String

__init__

def __init__(out self, message: String)

write_to

def write_to[W: Writer](self, mut writer: W)

WsFrame

struct WsFrame

A single WebSocket frame.

Represents the decoded wire form: header fields extracted and payload already de-masked (clients unmask on receive).

Owns the payload buffer.

Fields: fin: True if this is the final fragment of a message. rsv1: Extension bit RSV1 (must be False unless extension negotiated). opcode: Frame opcode (see WsOpcode.*). masked: True if the payload was masked on the wire (client→server only). payload: The unmasked payload bytes.

Example:

var frame = WsFrame.text("hello")
var wire = frame.encode(mask=True) # client sending to server

Implements Movable, Writable

Fields
fin: Bool
rsv1: Bool
opcode: UInt8
masked: Bool
payload: List[UInt8]

__init__

def __init__(out self, opcode: UInt8, payload: List[UInt8], fin: Bool = True, rsv1: Bool = False, masked: Bool = False)

text

def text(msg: String) -> Self

Create a text (UTF-8) frame.

Args
msg: The UTF-8 text payload.

binary

def binary(data: List[UInt8]) -> Self

Create a binary frame.

Args
data: The raw binary payload.

ping

def ping(data: List[UInt8] = List()) -> Self

Create a PING control frame (max 125 bytes payload).

Args
data: Optional PING payload (echo'd back in PONG, ≤125 bytes).

pong

def pong(data: List[UInt8] = List()) -> Self

Create a PONG control frame.

Args
data: The payload from the corresponding PING.

close

def close(code: UInt16 = UInt16(1000), reason: String = "") -> Self

Create a CLOSE control frame.

Args
code: Close status code (see WsCloseCode.*).
reason: UTF-8 reason phrase (≤123 bytes after encoding).

encode

def encode(self, mask: Bool = False) -> List[UInt8]

Encode this frame to its RFC 6455 wire representation.

With mask=True the frame is masked with a fresh 4-byte key from the OS CSPRNG, as RFC 6455 sec 5.3 requires of every client frame. This used to be an all-zero key "for testing", and every client frame flare sent went out that way: masking with zeros leaves the payload unchanged on the wire, which is exactly what the mask exists to prevent (intermediary cache poisoning). Tests that need fixed bytes call encode_with_key.

Args
mask: True for a client-to-server frame.

Raises WsProtocolError: If rsv1 is set without a negotiated extension, or if a control frame payload exceeds 125 bytes.

encode_with_key

def encode_with_key(self, mask: Bool, key: SIMD[.uint8, 4]) -> List[UInt8]

Encode this frame with an explicit 4-byte masking key.

Args
mask: True to apply the masking key.
key: The 4-byte masking key (ignored when mask=False).

Raises WsProtocolError: If a control frame payload exceeds 125 bytes.

decode_one

def decode_one(data: Span[UInt8], allow_rsv1: Bool = False, max_payload: Int = Int(16777216)) -> _DecodeResult

Parse one frame from data.

Args
data: Raw bytes from the socket (may contain more than one frame).
allow_rsv1: Accept a set RSV1 bit. Pass True only on a connection that negotiated an extension defining it (permessage-deflate, RFC 7692); the default rejects it per RFC 6455 sec 5.2, which requires a receiver to fail the connection on a reserved bit no negotiated extension gives meaning to.
max_payload: Largest payload accepted, checked against the declared length as soon as it is parsed, before the payload has arrived.

Raises WsProtocolError: If the frame violates RFC 6455 (bad RSV bits, a reserved opcode, fragmented control frame, etc.). Error: If data is too short to contain a complete frame.

is_control

def is_control(self) -> Bool

Return True if this is a control frame (CLOSE, PING, or PONG).

Control frames MUST NOT be fragmented (RFC 6455 §5.5).

text_payload

def text_payload(self) -> String

Decode the payload as a UTF-8 string with validation.

Validates that the payload is well-formed UTF-8 per RFC 6455 §8.1. Raises WsProtocolError on invalid sequences.

Raises WsProtocolError: If the payload contains invalid UTF-8.

write_to

def write_to[W: Writer](self, mut writer: W)

Functions

ws_frame_length

def ws_frame_length(data: Span[UInt8]) -> Int

Total length of the frame starting at data[0] once its header is in data, or -1 while the header is still incomplete.

Reads only the length fields; :meth:WsFrame.decode_one validates the frame. A receive loop reads until this many bytes are buffered instead of attempting a decode that raises on every short read.

Aliases

comptime DEFAULT_MAX_FRAME_BYTES = Int(16777216)

Largest frame payload a receiver accepts by default (16 MiB), the same bound :data:DEFAULT_MAX_DECOMPRESSED_BYTES puts on an inflated message. :meth:WsFrame.decode_one checks the declared length before any payload is buffered, so a header announcing a 4 GiB frame fails at once instead of having the reader grow its buffer towards it.

comptime WS_TOO_BIG_MARKER = String("frame too big")

Text in the :class:WsProtocolError that :meth:WsFrame.decode_one raises for a frame over its max_payload. Readers look for it to answer with CLOSE :data:WsCloseCode.MESSAGE_TOO_BIG (1009) before they drop the connection.