Changelog
View SourceAll notable changes to this project are documented here. Format loosely follows Keep a Changelog; versions follow Semantic Versioning.
0.1.1 — 2026-04-19
Security
ws_h1_upgrade:validate_request/1,2no longer crashes on a malformedSec-WebSocket-Keyheader; invalid base64 now surfaces as{error, bad_sec_websocket_key}.ws_deflate:inflate/3,4caps inflated output (default 64 MiB, configurable) and returns{error, {inflate_too_big, _}}past the bound — defuses the classic permessage-deflate bomb.ws_client:connect/2caps pre-upgrade byte accumulation via a newmax_handshake_sizeoption (default 64 KiB). Exceeding it returns{error, handshake_response_too_big}.ws_h1_tcp_server:start_link/1gains the samemax_handshake_sizeoption (default 64 KiB). Over-limit returns{error, handshake_too_big}and the socket is closed.
Tests
- New
ws_security_SUITEwith 11 targeted cases covering each of the above plus state-machine invariants (send during closing, handler init stop, ordered multi-frame send).
Documentation
docs/embedding.md— new "Hardening" section summarising the embedder-side defences: handshake caps, timeouts, concurrent connections, origin enforcement, deflate bombs, TLS defaults, close-code handling.docs/errors.md— new "Size-limit errors" table.
Housekeeping
- Apache-2.0 copyright header added to every
.erlfile.
0.1.0 — 2026-04-19
Initial release.
Frame codec
- RFC 6455 encode / decode for all opcodes (text, binary, ping, pong, close, continuation).
- Masking / unmasking (32-bit XOR), symmetric and streamable.
- Fragmentation reassembly across continuation frames, with an open fragment state machine.
- UTF-8 validation for text payloads and close reasons via an inlined Hoehrmann DFA, streaming-safe across fragment boundaries.
- Close-code validation per RFC 6455 §7.4 (
ws_close). Reserved codes 1004 / 1005 / 1006 / 1015 rejected on the wire; 3000–4999 accepted for registration / application use. - Size guards:
max_frameandmax_messageoptions on the parser, enforced during single-frame decode and fragment accumulation.
Handshake helpers
ws_h1_upgrade— server-side validation ofUpgrade,Connection,Sec-WebSocket-Key,Sec-WebSocket-Version;Sec-WebSocket-Acceptgeneration; subprotocol negotiation; client-side key generation, request build, 101 response validation.ws_h2_upgrade— RFC 8441 extended CONNECT pseudo-header validation (:method=CONNECT,:protocol=websocket,:scheme,:authority,:path); server response builder; client request builder that refuses to issue a CONNECT when the peer has not advertisedSETTINGS_ENABLE_CONNECT_PROTOCOL = 1.ws_h3_upgrade— RFC 9220 mirror of the H2 helpers.
Session
ws_session—gen_statemdriving the session. Statesready_wait -> open -> closing. Auto-responds to peer pings with matching pongs; surfaces ping / pong to the handler for custom behaviour.- Orderly close handshake: on receiving a close frame, echoes a close back (only once) before exiting normally. Peer-initiated protocol violations trigger a close frame with the matching code (1002 protocol error / 1007 invalid UTF-8 / 1009 message too big) followed by socket shutdown.
ws_handlerbehaviour:init/2,handle_in/2,handle_info/2,terminate/2. All callbacks canreplywith outbound frames.
Transport layer
ws_transportbehaviour —send/2,activate/1,close/1,controlling_process/2,classify/2,recv/2(optional, used by the client during the HTTP/1.1 handshake),peername/1(optional).ws_transport_gen_tcp— referencegen_tcptransport used by tests.ws_transport_ssl— OTPssltransport used bywss://client connections.
Reference server
ws_h1_tcp_server— a minimalgen_tcpacceptor + HTTP/1.1 upgrade driver built on top of the library helpers. Supports plain TCP and TLS via thetlsoption. Doubles as a runnable example and the server-side driver ofws_examples_SUITE.
Client
ws_client:connect/2forws:///wss://URLs. Builds the RFC 6455 upgrade request, validates the 101 response (includingSec-WebSocket-Acceptcross-check), starts aws_sessionin client mode with the user handler.- Automatic subprotocol, extension, origin, and extra-header handling on the request side.
Extensions
ws_deflate— RFC 7692 permessage-deflate.- Server-side negotiation of client offers with configurable takeover / window-bits policy; ignore-on-disagreement semantics.
- Client-side offer builder and server-response parser.
- Inflate / deflate primitives with takeover management.
Examples
examples/echo_server.erl— RFC 6455 echo server backed byws_h1_tcp_server.examples/echo_client.erl— synchronous send-and-wait client, usesws:connect/2.examples/chat_server.erl— broadcast chat server usingpgfor fan-out between sessions.
Tests
- 142 EUnit tests across codec, close codes, handshake helpers, deflate.
- 4 PropEr properties: mask involution, round-trip in both directions, chunked-delivery preserves messages.
- 25 Common Test cases total:
- 10 in
ws_session_SUITE— text / binary / large-payload echo, ping/pong, fragmentation, orderly-close, server-initiated close, bad-UTF-8 rejection, oversize-frame rejection, handler info fan-out. - 3 in
ws_client_SUITE— client↔server round-trip. - 12 in
ws_examples_SUITE— end-to-end coverage of theexamples/modules plus subprotocol negotiation, 20 concurrent clients, TLSwss://round-trip, 512 KiB payload, fragmented text delivered raw.
- 10 in
- Autobahn compliance suite (
WS_RUN_AUTOBAHN=1) — 300 cases across sections 1–9. All OK / NON-STRICT / INFORMATIONAL; zero failures.
Documentation
README.md— quickstart with server and client examples, module map, embedder integration notes.docs/guide.md— tutorial (mental model, handler, server, client, sending frames, closing, subprotocols, TLS, limits). Every code snippet is mechanically verified byws_docs_snippets_SUITE.docs/embedding.md— HTTP/1.1, RFC 8441 (HTTP/2), and RFC 9220 (HTTP/3) integration patterns plus instructions for writing a customws_transport.docs/errors.md— every failure mode the library surfaces, with close codes and remediation.docs/features.md— RFC coverage, hardening list, scope boundaries, full module map.LICENSE— Apache-2.0.