# Verification report - RustProxy 0.24.5 ## Scope RustProxy 0.24.5 is a protocol-framing and cache-memory maintenance release over 0.24.4. It keeps the 0.24.4 process-local THP mitigation, fixes the H3 -> H1 boundary for actually empty request bodies whose length is initially unknown, and hardens the existing HOT RAM -> COLD disk cache lifecycle without changing the COLD storage format. ## Source contracts reviewed - `ReceiveBody` in `src/http3.rs` reports end-of-stream only after the H3 DATA side reaches EOF and trailers are resolved; absence of `Content-Length` alone is not treated as proof of an empty body. - `normalize_h3_h1_unknown_body()` runs only for HTTP/3 requests selected for an HTTP/1.1 upstream and only when no declared/exact body length is already available. - EOF replaces the request body with `Body::empty()`. Non-empty first frames are replayed through `ReplayBody` and the remaining request body stays streaming. - HTTP/2 upstreams, non-H3 downstreams and declared `Content-Length` requests are not pre-read by this normalization. - The change is generic to body-capable methods; there is no Proxmox-specific or DELETE-to-H2 fallback. - Published HOT objects are bounded by `max_bytes` using body backing capacity plus directly owned metadata and a conservative HOT-index charge; logical payload bytes are reported separately. - Fill buffers reserve a bounded transient budget before growth, enforce `max_object_bytes` per chunk, and make HOT LRU room before further cache-buffer allocation. Failure leaves the response streaming uncached. - HOT -> COLD demotion moves the `Entry` rather than cloning the payload. The `Bytes` allocation remains charged to transient RAM while queued/writing and disappears from the persisted `ColdEntry` after the write completes. - The COLD writer queue is bounded by both object count and bytes; full COLD reads/promotions/revalidation reads reserve transient RAM before loading a body. - Global `cache.enabled=false` is authoritative over vhost overrides. HOT/object values no longer have the old artificial 1 GiB configuration ceiling. - Settings exposes conservative/recommended/performance presets derived from effective host/cgroup memory, plus non-blocking high-budget/headroom and inconsistent transient/object/queue warnings. A 2 GiB effective-memory VM gets approximately 400 MiB HOT / 96 MiB transient / 16 MiB max object / 48 MiB COLD queue under the recommended profile. - Release identity is 0.24.5 across Cargo/package/UI/OpenAPI/release helpers. The existing dependency graph is unchanged; only the root `rust-proxy` package version changes. ## Verification status in this workspace | Check | Status | |---|---| | `python3 scripts/preflight.py` | PASS | | `python3 scripts/langs_check.py` | PASS | | Browser JavaScript `node --check` | PASS | | Shell `bash -n` | PASS | | Python syntax / bytecode compile | PASS | | Docker agent `go test ./...` / `go vet ./...` / `go build ./...` | PASS | | Existing `Cargo.lock` dependency graph | PRESERVED; root package version updated to 0.24.5 | | `python3 scripts/check_source.py` | PASS | | `python3 scripts/release_smoke.py` | PASS | | `./dev.sh fmt` / `cargo fmt --all` | BLOCKED: Rust/Cargo toolchain unavailable in this workspace | | `./dev.sh check` / `cargo check --locked --all-targets` | BLOCKED: Rust/Cargo toolchain unavailable in this workspace | | `./dev.sh test` Rust phase | BLOCKED: Rust/Cargo toolchain unavailable in this workspace | | H1/H2/H3 live method matrix | test-host acceptance gate | | Proxmox DELETE H3 access-log verification | test-host acceptance gate | | HOT 8 MiB sustained-load/RSS acceptance | test-host acceptance gate | | HOT 2 GiB bounded-admission acceptance | test-host acceptance gate | | 5 s HOT -> COLD demotion/RSS/transient drain | test-host acceptance gate | | Oversized-object streaming without full cache buffering | source regression added; runtime acceptance gate remains | | Concurrent COLD read/write under small transient budget | test-host acceptance gate | ## Protocol acceptance target Run GET/POST/PUT/PATCH/DELETE over H1, H2 and H3. For DELETE, test both an empty body and a body-bearing request (use a mock upstream if the chosen Proxmox endpoint does not accept a DELETE body). The original H3 empty DELETE must no longer produce `501`; H1/H2 behavior must remain unchanged; Proxmox must receive `DELETE` and the same URI; and a raw HTTP/1.1 upstream must show non-chunked zero-length framing for the empty H3 case. For cache acceptance, test a small 8 MiB HOT tier under sustained traffic, a deliberately large 2 GiB HOT tier, `cold_after_seconds=5`, a response above `max_object_bytes`, and concurrent COLD promotion/demotion under a small transient limit. Published `hot_allocated_bytes` must remain within the HOT limit; transient/queue usage must drain after COLD persistence; large responses must keep streaming after their cache candidate is rejected; and RSS must plateau rather than track total traffic volume. See [V0.24.5_AUDIT.md](V0.24.5_AUDIT.md) for the source/spec matrix and remaining runtime gates.