Documentation
¶
Overview ¶
Package wsframe decodes WebSocket frames per RFC 6455.
Wrap-vs-native judgement
Native. RFC 6455 is fully public; the wire format is a tight bit-packed header (FIN/RSV/opcode/MASK/payload-len) with two variable-length escape hatches (extended 16-bit and extended 64-bit payload length) and an optional 4-byte mask key. The walker handles fragmentation (Continuation opcode 0x0 after a Text/Binary opener) and demasks payload bytes when the MASK bit is set (client→server frames per §5.3 must be masked). Operators paste WebSocket frame bytes from a mitmproxy / wsdump / Chrome DevTools Network panel export and inspect every documented field. Pure offline parser — no transport, no hardware.
What this package covers
Frame header (2 bytes minimum): byte 0: FIN | RSV1 | RSV2 | RSV3 | opcode (4) byte 1: MASK | payload-len (7)
Extended payload length: when payload-len == 126, the next 2 bytes are the actual length (uint16 BE); when payload-len == 127, the next 8 bytes are the actual length (uint64 BE).
Mask key: 4 bytes immediately after the length field when MASK == 1. Per RFC 6455 §5.3, every client→server frame MUST be masked; server→client frames MUST NOT be masked.
Opcodes (RFC 6455 §11.8): 0x0 Continuation 0x1 Text (UTF-8) 0x2 Binary 0x3-0x7 reserved (non-control) 0x8 Close 0x9 Ping 0xA Pong 0xB-0xF reserved (control)
Payload demasking: when MASK == 1, each payload byte b[i] is XORed with maskKey[i%4] to recover plaintext.
Close frame body (opcode 0x8): first 2 bytes are a uint16 BE status code (RFC 6455 §7.4.1), remaining bytes are optional UTF-8 reason text. The status-code table covers documented 1xxx codes (1000-1015) plus the user/library ranges (3000-3999 / 4000-4999).
Text/Binary frame body: text is surfaced as a string when the bytes are valid UTF-8 and free of control characters; otherwise as uppercase hex. Binary frames always surface as uppercase hex.
Multi-frame buffer walking: a single buffer may carry several concatenated frames (server→client streams often do this). The walker iterates frame-by-frame until the buffer is consumed and surfaces a summary of opcodes seen.
What this package does NOT cover (deliberately out of scope)
HTTP/1.x Upgrade handshake (Sec-WebSocket-Key / Accept / Version / Extensions / Protocol) — already handled by internal/httpmsg (the Upgrade headers are preserved verbatim; this package starts at the first frame after the 101 Switching Protocols response).
Per-message Deflate (RFC 7692) — RSV1 indicates that the payload is permessage-deflate compressed; we surface RSV1=true and the raw (still-compressed) payload as hex. Operators who need cleartext can pipe the bytes through their own decompressor.
Subprotocols (e.g. MQTT-over-WebSocket, STOMP, graphql-ws) — opcode 0x1/0x2 payloads are surfaced as text or hex; subprotocol-specific framing belongs in a sibling helper.
Statefulness across frames — fragmentation is detected (FIN=0 + opcode!=0 on opener; FIN=0/1 + opcode=0 on continuation) and surfaced in each frame's flags, but the package does not reassemble continuation chains into a single logical message.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CloseInfo ¶
type CloseInfo struct {
StatusCode int `json:"status_code"`
StatusName string `json:"status_name"`
Reason string `json:"reason,omitempty"`
}
CloseInfo is the parsed Close-frame body (opcode 0x8).
type Frame ¶
type Frame struct {
FIN bool `json:"fin"`
RSV1 bool `json:"rsv1"`
RSV2 bool `json:"rsv2"`
RSV3 bool `json:"rsv3"`
Opcode int `json:"opcode"`
OpcodeName string `json:"opcode_name"`
IsControl bool `json:"is_control"`
Masked bool `json:"masked"`
PayloadLenRaw int `json:"payload_len_raw"`
PayloadLength uint64 `json:"payload_length"`
MaskKey string `json:"mask_key,omitempty"`
HeaderBytes int `json:"header_bytes"`
FrameBytes int `json:"frame_bytes"`
PayloadHex string `json:"payload_hex,omitempty"`
PayloadHexClip bool `json:"payload_hex_truncated,omitempty"`
PayloadText string `json:"payload_text,omitempty"`
Close *CloseInfo `json:"close,omitempty"`
Notes []string `json:"notes,omitempty"`
}
Frame is one decoded WebSocket frame.