# RustProxy 0.24.0 specification audit ## Scope 0.24.0 changes downstream HTTP/2 connection retirement and extracts runtime system statistics into platform backends. Existing H1/H2/H3 routing, RFC 8441 WebSocket support, legacy WebSocket compatibility (including iLO4-class origins), cache and proxy behavior are retained unless stated below. ## HTTP/2 lifecycle - `http2.idle_timeout_seconds` defaults to 300 seconds and remains independent from maximum lifetime. - `http2.max_connection_lifetime_seconds` defaults to `0`, which disables the absolute lifetime limit. - `http2.drain_timeout_seconds` defaults to 10 seconds and bounds graceful draining after shutdown begins. - Idle qualification checks both recent H2 transport activity and the active stream count immediately before retirement. - Idle or lifetime retirement calls Hyper graceful shutdown, which emits HTTP/2 GOAWAY, refuses newer streams and continues polling already accepted streams. - Active response bodies, including RFC 8441 Extended CONNECT/WebSocket bodies, hold a stream lease until end-of-stream/error/drop. - After accepted streams finish, the H2 connection future completes and the TCP transport is dropped normally. A drain timeout forces transport closure if a stream does not finish. - Process shutdown uses the same GOAWAY/drain path; its drain is additionally capped by the process grace period. Source regressions cover idle GOAWAY, active-stream idle suppression, lifetime GOAWAY plus forced drain timeout, and successful active-stream completion during lifetime drain. ## Settings organization The former top-level **HTTP/2 connections** Settings tab is now **HTTP connections** with HTTP/2 and HTTP/3 sub-tabs. HTTP/2 lifecycle settings still save through the live `http2` section. HTTP/3 remains stored per TLS listener and requires restart, but its QUIC enablement, advertisement lifetime, connection/stream limits and idle timeout are edited from the HTTP/3 sub-tab. The Listeners editor retains bind/TLS/H2/h2c controls and preserves each listener's existing H3 configuration when unrelated listener fields are saved. Legacy `/settings?tab=http2` links are normalized to `/settings?tab=connections`. ## System statistics/platform runtime `system_stats` is the shared sampling module. Linux retains the existing `linux_procfs` source and the same names, units and `/proc`/cgroup semantics for CPU, process CPU, memory, RSS breakdown, FDs, threads, load, network, process I/O and cgroup memory. FreeBSD, OpenBSD and NetBSD use the BSD backend and native OS mechanisms where available: `sysctl`, `getrusage`, `ps` and `netstat`. A metric that cannot be obtained with the same meaning is left `None`; values are not synthesized. Other Unix targets report the platform and leave unavailable system metrics unsupported/null. The status payload now includes `platform`; Proxy Process displays it. Prometheus also exposes `rust_proxy_platform_info{platform="..."} 1`. ## Retained WebSocket compatibility contracts The 0.23.3 legacy WebSocket mode remains opt-in per vhost. It continues to use HTTP/1.1 upstream, align Host and Origin with the configured backend, tolerate the documented legacy 101 framing, and keep Sec-WebSocket-Accept/subprotocol proof strict. This retained path is separate from RFC 8441 H2 WebSocket Extended CONNECT, whose accepted stream participates in the new H2 drain accounting. ## Release verification Source-side Python/OpenAPI/language/JavaScript/shell/release-package checks are run in this workspace. The workspace does not provide `cargo`, `rustc` or `rustfmt`, so `cargo fmt --all`, `cargo check --locked --all-targets`, `cargo test --locked --all-targets`, release build acceptance, and native BSD compiler/runtime execution remain release-host gates. No passing Rust compiler result is claimed here.