feat(capture): WebSocket transport — hardened RFC 6455 subset (ADR-0008)#61
Merged
Conversation
The transport foundation for live capture. Zig's std has no WebSocket, and the zero-config build (ADR-0004) has no dependency mechanism without ejecting, so ADR-0008 records the decision to hand-roll a bounded RFC 6455 subset that Studio owns — keeping the untrusted-input hardening at the entry point where it matters most. src/capture/ws.zig is a pure codec (byte buffers, no sockets), fully unit-testable: both handshake halves (server-accept + client-request), base framing at every length form, fragmentation reassembly, and control frames. Hardening: masking enforced per role (client->server MUST be masked, server->client MUST NOT), per-frame and per-message size bounds, a fragment-count cap, and rejection of reserved bits, unknown opcodes, and malformed control frames. Adds the src/capture/ aggregate root, wires it into the root test block, and catches up the ADR index with 0006-0008. Closes #54.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #54. First issue of S5 — Live capture.
Summary
The transport foundation for the live-capture proxy. Zig's std has no WebSocket
implementation, and the zero-config build (ADR-0004) has no dependency mechanism
without ejecting the runner — so ADR-0008 records the decision to hand-roll a
bounded RFC 6455 subset that Studio owns. That keeps the untrusted-input
hardening at the rawest entry point in the app (raw socket bytes from an
arbitrary peer) fully in our control.
What's here
permessage-deflateexplicitly deferred to post-0.5, behind this sameboundary).
src/capture/ws.zig— a pure codec (byte buffers, no sockets), so thewhole thing is unit-testable without a network:
Sec-WebSocket-AcceptviaSHA-1+ base64) and client-request — since MITM plays both roles.encode + decode.
Assembler); close-frame build/parse.src/capture/capture.zigaggregate root, wired into the root test block.indexed).
Hardening (untrusted input)
server→client MUST NOT — violations rejected (RFC 6455 §5.1).
cap (1024); oversize payloads rejected before the payload is read.
rejected. Truncated buffers return
null(read more), never over-read.Tests
15 new codec tests (138 total, up from 123), including the RFC 6455 §1.3 accept
example, round-trips at each length form (masked + unmasked), and every rejection
path above.
Verification
native test -Dplatform=null→ 138/138.native build(ReleaseFast) → clean (the lazy-analysis double-check).zig fmt --checkclean.Not here (later S5 issues)
Socket I/O and the proxy loop (#56); OCPP-J decode (#55). The codec is
socket-free by design.