Development
cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace # unit, corpus, property and end-to-end testsCI (.github/workflows/ci.yml) runs these with RUSTFLAGS=-D warnings,
plus cargo deny and a wasm job. The wasm test components
(crates/roxy-wasm/test-components) are their own workspace, checked in
prebuilt; the wasm job rebuilds them from source and runs the tests that
load them. After changing one, rebuild with its build.sh and commit.
Crates: architecture. Working practices: CLAUDE.md.
Testing
- Smuggling corpus (
crates/roxy-http/tests/corpus/): CL.TE, TE.CL, TE.TE obfuscations, duplicate lengths, obs-fold, bare LF,%2e%2epath climbs, Host/authority mismatches, CRLF in header values, and more, each with an expected reason code; the acceptance test for the rejection rules. - Property tests: URL normalisation is idempotent; serialise → parse round-trips to an equal canonical model.
- Golden tests (
insta) for rule diagnostics (crates/roxy-rules/tests/snapshots/);cargo insta reviewwhen a message changes on purpose. - End-to-end tests (
crates/roxy/tests/): roxy, a local TLS upstream with a test CA, and HTTP/1.1, HTTP/2 and WebSocket clients: allow, deny, effects, metrics, reload, capture, addons. - Benchmarks (
criterion): rule evaluation for a 100-rule policy (target under 5 µs), metric recording, address-list lookups.cargo bench -p roxy-rulesor-p roxy-proxy.
Fuzzing
fuzz/ is a cargo-fuzz workspace (nightly;
fuzz/README.md)
with targets for:
- the HTTP/1.1 request head (the canonical form is a fixed point of parse → serialise → parse);
- the chunked body decoder;
- the content-coding decoders;
- the h2 → canonical mapping;
- the URL normaliser (idempotent, no dot segments survive);
- the ClientHello sniffer (verdicts never change as more bytes arrive);
- the WebSocket frame decoder;
- the rule lexer, parser and compiler;
- policy evaluation (making an input unavailable either changes nothing or fails closed, never a different decision).
Seeds: the smuggling corpus and the example configs.
.github/workflows/fuzz.yml runs every target nightly (5 minutes each,
growing a cached corpus) and for 60 seconds on pull requests touching a
fuzzed parser. A crash becomes a regression test in the crate it hit.
Releasing
Push a vX.Y.Z tag; see RELEASING.md.