websocket_frame.nx
buildroot/runtime/websocket_frame.nx
about
websocket_frame.nx -- RFC 6455 WebSocket frame parser + builder.
Parses and emits individual frames. The handshake (HTTP
Upgrade + Sec-WebSocket-Key + Sec-WebSocket-Accept) goes in a
separate websocket_handshake.nx that will build on sha1.nx +
base64.nx + this module.
Frame layout (RFC 6455 ยง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 |
+-------------------------------- - - - - - - - - - - - - - - - +
Opcodes:
0x0 continuation frame
0x1 text frame (UTF-8)
0x2 binary frame
0x8 close
0x9 ping
0xA pong
Invariants:
WS1 Client -> server frames MUST be masked (RFC). We set
this flag on encode per the `masked` arg; callers MUST
supply a random 4-byte mask when sending from a client.
WS2 Server -> client frames MUST NOT be masked.
WS3 Payload length encoding: 7-bit inline (0..125), or
126 + 16-bit extended, or 127 + 64-bit extended.
WS4 Masking is reversible -- apply mask twice = identity.
dependencies 1 imports · 0 importers
imports: syscalls.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| 54 | struct WsFrame { |
consts
| 44 | const WS_ERR_SHORT: i64 = -1 |
| 45 | const WS_ERR_LONG: i64 = -2 |
| 47 | const WS_OP_CONT: i64 = 0x0 |
| 48 | const WS_OP_TEXT: i64 = 0x1 |
| 49 | const WS_OP_BINARY: i64 = 0x2 |
| 50 | const WS_OP_CLOSE: i64 = 0x8 |
| 51 | const WS_OP_PING: i64 = 0x9 |
| 52 | const WS_OP_PONG: i64 = 0xA |
functions
| 71 | func ws_parse_frame(buf: *u8, n: i64, off: i64, f: *WsFrame) -> i64 {
called by 1: main |
| 130 | func ws_apply_mask(buf: *u8, off: i64, n: i64, mask_key: i64) -> i64 {
called by 1: main |
| 152 | func ws_build_header(out: *u8, cap: i64,
called by 1: main |
| 207 | func main() -> i64 { |