4.2 KiB
RustProxy 0.22.1 specification audit
Scope
This audit covers the 0.22.1 delta over 0.22.0: Cache administration UI polish, HTTP/2 RFC 8441 WebSocket, cleartext HTTP/2 prior knowledge, and identifiable/killable active tunnels. The 0.22.0 cache audit remains historical evidence for the retained cache implementation.
Requirement matrix
| Requirement | Source implementation | Regression / verification |
|---|---|---|
| PURGE/BAN form in a modal beside Purge selected scope | src/admin/web/index.html, cache-panel.js |
JS syntax + source-release checks |
| Active BAN list in a separate modal | src/admin/web/index.html, cache-panel.js |
JS syntax + source-release checks |
| BAN/PURGE messages cannot dereference a missing status node | null-safe operationMessage(...) |
source-release marker + UI syntax checks |
RFC 8441 CONNECT + :protocol=websocket |
proxy/websocket.rs, proxy/mod.rs |
tests/http2.rs + module tests |
| RFC 8441 per-vhost opt-in beside RFC 9220 | vhost.rs, config.rs, vhosts.js |
config/unit source regressions |
Listener advertises SETTINGS_ENABLE_CONNECT_PROTOCOL only where required |
config::Snapshot::websocket_rfc8441_on, server.rs |
source/config regression; Hyper builder contract |
| H2 client -> H1 upstream WebSocket | H2 request DATA <-> upgraded H1 byte bridge in bridge_h2_to_h1 |
source regression + compiler/live release-host gate |
| H2 client -> explicit H2 upstream | preserve H2 CONNECT/Protocol and meter request/response bodies | source regression + compiler/live release-host gate |
| WebSocket cancellation / idle timeout | TunnelSession cancellation + H2 idle watcher + existing H1/H3 timeout loops |
source review; live release-host gate |
| h2c explicit enable/disable | Listener.h2c, Settings UI and validation |
transport_config / vhost tests |
| h2c prior knowledge | HTTP/2 connection-preface detection in server.rs |
server prefix unit test + live release-host gate |
HTTP/1.1 Upgrade: h2c |
deliberately deferred; no fake 101 path is shipped |
docs + source-release guard |
| Stable active tunnel ID | request/exchange ID stored in TunnelSession |
source review/API contract |
| List client/host/upstream/protocol/duration/RX/TX | TunnelInfo, GET /api/tunnels, modal |
OpenAPI + source-release checks |
| Kill one tunnel | POST /api/tunnels/{id}/kill cancellation |
OpenAPI + source-release checks |
| Audit close reason | tunnel.kill audit with operator reason |
admin source regression |
| Main dashboard H1/H2/H3 tunnel stats | metrics + overview card | JS/source checks + Prometheus contract |
| Overview card geometry is shared across both visual rows | one stats-grid containing primary + WebSocket/H2/H3/TLS cards |
source-release check |
| Full Cache Target / Cache key + tags remain retrievable when cells ellipsize | keyboard/click copy cells in cache-panel.js, full value in title |
JS/source-release check |
Protocol notes
RFC 8441 Extended CONNECT is connection-scoped at the HTTP/2 SETTINGS level. RustProxy therefore advertises the capability on a listener connection only when at least one bound vhost enables RFC 8441; request routing still enforces the selected vhost's own flag.
h2c in 0.22.1 means HTTP/2 prior knowledge. The legacy HTTP/1.1 Upgrade: h2c bootstrap is not accepted because a correct implementation must carry the initiating H1 request into HTTP/2 stream 1 after the 101 response. The current Hyper integration does not expose a safe bootstrap path for that operation, so the release does not claim partial support.
Accept-Ranges policy
RustProxy does not globally inject Accept-Ranges: bytes into ordinary responses. It preserves the origin header where representation semantics remain unchanged and synthesizes Accept-Ranges: bytes for a cached single-range response handled by RustProxy. Transform/compression paths remove incompatible range advertising.
Release gate
The packaging workspace has no Rust toolchain. JavaScript/JSON/language/source/package checks can be executed here, but cargo check --locked, cargo test --locked, Clippy, release build and live H2/h2c/RFC8441 interoperability remain mandatory on a Rust-enabled release host before deployment.