Under construction

This documentation is still in progress. Some information may be incomplete or out of date. Please check back later.

Docs/Conformance & testing

Running it

Conformance & testing

Two axes define httpjet's posture: LiteSpeed compatibility on the same configuration tree (LSWS 6.3.5 target — XML model, LSAPI, ETags, LSCache protocol, .htaccess), and standards conformance on the wire. Where they agree there is one right answer; where LiteSpeed made a deliberate choice a strict reading would call optional, httpjet matches LiteSpeed. Everything is held in place by ~1,900 tests, h2spec, fuzzing, CI interoperability jobs and the production deploy gates.

Conformance matrix

AreaStandard / referenceStatus
HTTP/1.1RFC 9110 · RFC 9111 · RFC 9112Strict framing, conditional requests, single + multipart ranges (RFC 9110 §14), Vary, 103 Early Hints (RFC 8297); RFC 9112 request-target forms enforced at intake (origin-form; * OPTIONS-only; absolute-form reduced with its authority replacing Host), 405 for CONNECT, 400 for authority-form/raw #/bare-LF lines, Host required on HTTP/1.1 and validated by the h2 authority rule
HTTP/2RFC 9113 (native hj-h2)146 / 146 h2spec 2.6.0 over TLS; h2c informative 145/146 (documented dual-protocol exception)
HPACKRFC 7541Zero-allocation codec; two fuzz targets
HTTP/3 / QUICRFC 9114 over RFC 9000 (quinn-proto), QPACK RFC 9204aioquic transfer and OTel trace fixtures in CI; migration disabled
TLSrustls + aws-lc-rs · RFC 8446 mandatory suiteSNI mirrors OpenLiteSpeed; mTLS with CRLs; single-use tickets, 0-RTT off
ACMERFC 8555 §8.1 / §8.3 (Pebble v2.10.1 fixtures)HTTP-01 and DNS-01 behind --features acme
OCSPRFC 6960 with the lightweight-profile conventions (SHA-256 issuer identity, bounded fetch — not full client conformance)Behind --features ocsp
PROXY protocolv2 binary + v1 textPer-listener, fail-closed, pre-TLS/pre-sniff; loopback claims refused
LSAPINative wire codec (vendored php-src lsapidef.h)Parity with lsphp; fuzzed response-header parser
FastCGIFastCGI 1.0 (65,535-byte records, application record types)Synthetic responder interoperability
ETagLiteSpeed fileETag=28"<size>-<mtime>-<inode>;;;", byte-for-byte
.htaccessApache mod_rewrite / mod_access / mod_auth_basic / mod_headers subsetDirective and flag parity for the common core; Header boundary characterized by fixtures
OpenTelemetryOTLP HTTP/protobuf, W3C traceparent (version 00)Behind --features otel; decoded-protobuf tests
LiteSpeed parityRetired differential matrix vs LSWS 6.3.511 / 11 on the retained behaviors; now exercised continuously by production

LiteSpeed parity and the clean-room boundary

Differential testing against a live LiteSpeed reached 11/11 on ETag format, .html→PHP dispatch, LSAPI encoding and rewrite-flag semantics before the apparatus was retired: httpjet is now the same-config drop-in serving the live tree. The authoritative reference for LiteSpeed's exact behavior was the GPL OpenLiteSpeed source, read to extract behavior and then reimplemented from scratch — no OpenLiteSpeed code was copied. httpjet itself is licensed GPL-3.0-only, with no paid edition or license key, and is independent of and not endorsed by LiteSpeed Technologies.

fileETag=28 · byte-for-byte
ETag: "4096-1718800000-1572934;;;"     # size-mtime-inode, three trailing semicolons — strict validators compare bytes

Suffix routing and the .html→PHP decision follow OpenLiteSpeed's order, including the source-disclosure guard: a script whose handler has no pool is a 503 and never falls through to static.

Test layers

LayerWhat it coversRun
unitPure logic per crate: config parsing, rewrite evaluation, HPACK, ETags, cache keys, ACME snapshots, OCSP profiles, FastCGI records.cargo test -p <crate>
integrationCrate boundaries: real .htaccess files through the engine (redirect_repro, header_compat), upstream groups on ephemeral ports, page-cache expiry/race tests, full-pipeline e2e and security regressions in the binary, the H1 corpus replay (2,333 seed/truncation/mutation cases).cargo test --workspace
live (#[ignore])Spawn lsphp, read real certificates, bind ports, QUIC round-trips, Pebble issuance. Run individually with their prerequisites; never as one batch.cargo test -- --ignored <name>
scriptsReal-server fixtures on isolated loopback listeners: h2spec, ACME/OCSP/admin runtime tests, the cache gates, memo parity, OCI smoke.see each page

The last full runs: the whole workspace suite green at the 0.0.5 release (2,028 passed / 0 failed); 2,016 at the 0.0.4 security review. A failure is a regression, not "pre-existing." Timing-flaky meta-assertions were deleted in June 2026 so the concurrency tests are deterministic.

CI and interoperability jobs

local reproduction
cargo test --locked -p httpjet --test h1_corpus -- --nocapture
cargo build --locked -p httpjet --features otel --bin httpjet
python3 -B scripts/ci-h2spec.py --binary target/debug/httpjet --h2spec h2spec
cargo test --locked -p httpjet --features otel traced_fast_and_bridged_requests
cargo test --locked -p httpjet --features otel traced_quic_roundtrip -- --ignored

Hosted execution evidence is tracked separately from local runs; a runner label being available is not proof a job executed.

Fuzzing

Eight cargo-fuzz targets share one invariant (never panic, never allocate unboundedly, agree with the reference decoder where one exists): h1_chunked_decode, h1_request_framing, hpack_decode, hpack_roundtrip, lsapi_resp_header, and — added in the 2026-10-06 review — qpack_decode, proxy_protocol_parse and lscache_control. Short ASan smoke runs of the original five covered 164,558 chunked, 739,373 framing, 452,899 HPACK-decode, 58,082 HPACK-roundtrip and 438,582 LSAPI-header executions without a finding.

bounded fuzz
FUZZ_TOOLCHAIN=nightly FUZZ_SECONDS=5 bash scripts/fuzz-bounded.sh h1_request_framing
python3 scripts/fuzz-seeds.py     # regenerate the shared seed corpus

Production gates

Beyond the suites, a deploy runs the cache-correctness gates (cross-URL, cross-scheme, cross-host, private tier, persistence), the fast-memo parity gate, the capsule purge gate and the h2spec gate. They are described with their failure classes on Page cache → deploy gates and Operations → deploy.

httpjet · documentation · synced to the source tree on 2026-10-13 (v0.0.5).
Source: github.com/faratech/httpjet · Home: httpjet.net · Found an error? Open an issue on the repository.