we (web engine): Experimental web browser project to understand the limits of Claude
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Implement WebSocket protocol (RFC 6455) in we-net #186

open opened by pierrelf.com

Goal#

Implement the wire-level WebSocket protocol (RFC 6455) in we-net, including the opening HTTP Upgrade handshake, frame parse/serialize, masking, fragmentation, close handshake, and the permessage-deflate extension. This is the transport layer that the JS API will sit on top of in the following issue.

Scope#

  • Opening handshake (client side)
    • Construct an HTTP/1.1 request with Upgrade: websocket, Connection: Upgrade, Sec-WebSocket-Version: 13, Sec-WebSocket-Key (16 random bytes, base64-encoded), optional Sec-WebSocket-Protocol, Sec-WebSocket-Extensions
    • Parse the server's 101 Switching Protocols response and verify Sec-WebSocket-Accept = base64(SHA-1(key + \"258EAFA5-E914-47DA-95CA-C5AB0DC85B11\"))
    • Reuse the Phase 6 TCP/TLS stack — ws:// over TCP, wss:// over TLS 1.3
    • Add SHA-1 to we-crypto (FIPS 180-4) since RFC 6455 mandates it; constant-time not required (the value is public). Document that SHA-1 is used only for the WebSocket handshake.
  • Frame layer
    • Parse and serialize frames per RFC 6455 §5.2: FIN, RSV1/2/3, opcode, MASK, payload length (7 / 7+16 / 7+64), masking key, payload
    • Opcodes: continuation (0x0), text (0x1), binary (0x2), close (0x8), ping (0x9), pong (0xA)
    • Client-to-server frames are always masked with a random 32-bit key
    • Fragmentation: reassemble continuation frames into a complete message; reject interleaved control frames within a fragmented data frame? — control frames are allowed between data fragments, must not be fragmented themselves
    • Validate text frames as UTF-8 (per RFC 6455 §8.1) — invalid UTF-8 closes the connection with status 1007
    • Maximum frame and message size limits (configurable; default 16 MiB)
  • Close handshake
    • 2-byte status code + optional UTF-8 reason
    • Defined codes: 1000, 1001, 1002, 1003, 1007, 1008, 1009, 1010, 1011, plus 3000–4999 application range
    • Echo close frame back; close TCP after both directions have sent close (or after timeout)
  • permessage-deflate extension (RFC 7692)
    • Negotiate via Sec-WebSocket-Extensions: permessage-deflate
    • Per-message DEFLATE compression with sliding window context (client_max_window_bits, server_max_window_bits, client_no_context_takeover, server_no_context_takeover)
    • Reuse the streaming DEFLATE implementation from the transform-streams issue (or share code)
  • Public Rust API in we-net
    • Async-ish (std::sync::mpsc or callback-driven) interface usable from JS
    • Sender half: send_text, send_binary, send_ping, close(code, reason)
    • Receiver half: surface inbound messages, pings, pongs, and close frames

Acceptance Criteria#

  • Open and close handshakes interoperate with a standard server (e.g. ws://echo.websocket.events once wss is verified separately, or a small embedded test server using the same implementation)
  • Text and binary messages round-trip including fragmented and large (>64 KiB) payloads
  • Server-sent pings are answered with matching pongs automatically
  • Invalid UTF-8 on a text frame triggers a close with status 1007
  • permessage-deflate round-trips messages and respects context-takeover parameters
  • A wss:// connection (TLS 1.3) round-trips messages
  • Unit tests: handshake validation (good and bad Sec-WebSocket-Accept), frame parse/serialize for each opcode and length encoding, masking round-trip, fragmentation reassembly, close handshake symmetry, permessage-deflate with and without context takeover
  • Conventions
    • cargo fmt --all --check
    • cargo clippy --workspace -- -D warnings
    • cargo test --workspace
    • SHA-1 implementation lives in we-crypto as a standalone module; no external dependencies
sign up or login to add to the discussion
Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:plc:meotu43t6usg4qdwzenk4s2t/sh.tangled.repo.issue/3mly7r6jykq23