nhttp_ws_frame (nhttp_lib v1.0.0)

View Source

WebSocket per-frame codec (RFC 6455).

Pure encode and decode for a single WebSocket frame. Stateless. For continuation reassembly and interleaved control frames, layer nhttp_ws on top of this module.

Server-to-client frames are unmasked, client-to-server frames must be masked (RFC 6455 §5.1).

Summary

Functions

Decode a masked WebSocket frame (client-to-server). Returns {ok, Message, Rest} on success, {more, MinBytes} if more data is needed, or {error, Reason} on protocol violation.

Decode a raw frame, returning Fin, Opcode, Payload, Rest separately. Used by the stateful message-level decoder for continuation reassembly. The role argument selects masked (server) or unmasked (client) parsing.

Decode an unmasked WebSocket frame (server-to-client). RFC 6455 §5.1: a server MUST NOT mask frames sent to clients.

Encode a WebSocket message as an unmasked frame (server-to-client).

Encode a WebSocket message with options. The only option is mask => boolean(), which defaults to false (server-to-client).

Encode a WebSocket message as a masked frame (client-to-server).

Map a complete (FIN=1) frame's opcode and payload to a ws_message/0. Text payloads are validated as UTF-8 (RFC 6455 §5.6 / §8.1). Close payloads are validated against the reserved-code ranges of RFC 6455 §7.4.1 and the reason is checked as UTF-8.

Map a frame's Fin bit, opcode and payload to a ws_message/0. Rejects fragmented frames (Fin=0). Fragmentation must be handled by the stateful message-level decoder.

Validate that a control frame is not fragmented and not too large (RFC 6455 §5.5: control frame payloads MUST be <= 125 bytes).

Types

close_code()

-type close_code() :: 0..65535.

decode_result()

-type decode_result() ::
          {ok, ws_message(), Rest :: binary()} | {more, MinBytes :: pos_integer()} | {error, term()}.

encode_opts()

-type encode_opts() :: #{mask => boolean()}.

raw_decode_result()

-type raw_decode_result() ::
          {ok, Fin :: 0 | 1, Opcode :: 0..15, Payload :: binary(), Rest :: binary()} |
          {more, MinBytes :: pos_integer()} |
          {error, term()}.

ws_message()

-type ws_message() ::
          {text, binary()} |
          {binary, binary()} |
          ping |
          {ping, binary()} |
          pong |
          {pong, binary()} |
          close |
          {close, Code :: close_code(), Reason :: binary()}.

ws_opcode()

-type ws_opcode() :: text | binary | close | ping | pong | continuation.

Functions

decode/1

-spec decode(binary()) -> decode_result().

Decode a masked WebSocket frame (client-to-server). Returns {ok, Message, Rest} on success, {more, MinBytes} if more data is needed, or {error, Reason} on protocol violation.

decode_raw/2

-spec decode_raw(binary(), client | server) -> raw_decode_result().

Decode a raw frame, returning Fin, Opcode, Payload, Rest separately. Used by the stateful message-level decoder for continuation reassembly. The role argument selects masked (server) or unmasked (client) parsing.

decode_unmasked/1

-spec decode_unmasked(binary()) -> decode_result().

Decode an unmasked WebSocket frame (server-to-client). RFC 6455 §5.1: a server MUST NOT mask frames sent to clients.

encode(Message)

-spec encode(ws_message()) -> iodata().

Encode a WebSocket message as an unmasked frame (server-to-client).

encode(Message, Opts)

-spec encode(ws_message(), encode_opts()) -> iodata().

Encode a WebSocket message with options. The only option is mask => boolean(), which defaults to false (server-to-client).

encode_masked(Message)

-spec encode_masked(ws_message()) -> iodata().

Encode a WebSocket message as a masked frame (client-to-server).

opcode_to_complete_message/2

-spec opcode_to_complete_message(0..15, binary()) -> {ok, ws_message()} | {error, term()}.

Map a complete (FIN=1) frame's opcode and payload to a ws_message/0. Text payloads are validated as UTF-8 (RFC 6455 §5.6 / §8.1). Close payloads are validated against the reserved-code ranges of RFC 6455 §7.4.1 and the reason is checked as UTF-8.

opcode_to_message/3

-spec opcode_to_message(0 | 1, 0..15, binary()) -> {ok, ws_message()} | {error, term()}.

Map a frame's Fin bit, opcode and payload to a ws_message/0. Rejects fragmented frames (Fin=0). Fragmentation must be handled by the stateful message-level decoder.

validate_control_frame/3

-spec validate_control_frame(0 | 1, 0..15, binary()) ->
                                ok | {error, control_frame_too_large | fragmented_control_frame}.

Validate that a control frame is not fragmented and not too large (RFC 6455 §5.5: control frame payloads MUST be <= 125 bytes).