wire / wire-format / websocket-frame
A WebSocket frame starts with a byte holding FIN + RSV1-3 + a 4-bit opcode, then a byte with the MASK bit and a 7-bit payload length (126 => next 2 bytes are the length, 127 => next 8 bytes). Client-to-server frames must be masked, adding a 4-byte masking key XORed over the payload.
aka: WebSocket data frame · ws frame · RFC 6455 frame
spec: RFC 6455
A compact frame over a TCP connection upgraded from HTTP (101 Switching Protocols). The length uses a 7/7+16/7+64-bit escalating encoding, a varint-like length-prefix scheme; the payload is a length-delimited value.
| field | size | meaning |
|---|---|---|
| FIN | 1 bit | 1 = final fragment of a message. |
| RSV1-3 | 3 bits | Reserved; 0 unless an extension (e.g. permessage-deflate) negotiated them. |
| Opcode | 4 bits | 0x0 continuation, 0x1 text, 0x2 binary, 0x8 close, 0x9 ping, 0xA pong. |
| MASK | 1 bit | 1 = payload is masked (mandatory for client->server frames). |
| Payload len | 7 bits | 0-125 = the length; 126 = read next 16 bits as length; 127 = read next 64 bits as length. |
| Extended payload length | 0/16/64 bits | Present only when the 7-bit length is 126 or 127; big-endian. |
| Masking key | 0 or 32 bits | Present iff MASK=1; XORed (key[i mod 4]) over each payload byte. |
| Payload data | = payload length | Application data (unmasked first if MASK was set). |
example:
81 05 48 65 6C 6C 6F
Unmasked text frame 'Hello': 0x81 = FIN + opcode 0x1 (text); 0x05 = MASK 0, length 5; 48 65 6C 6C 6F = ASCII 'Hello'.
see: http-status/101
agent: curl -H 'accept: application/json' wire.phall.io/wire-format/websocket-frame
or /wire-format/websocket-frame.json