Files
RustProxy/docs/V0.24.3_AUDIT.md
T
2026-10-07 08:51:04 +02:00

57 lines
6.5 KiB
Markdown

# RustProxy 0.24.3 specification audit
## Scope
0.24.3 is a focused runtime/UI maintenance release over 0.24.2. It reduces long-running Linux/glibc RSS retention in the transform-heavy path, keeps HTTP/2/H2C and HTTP/3 enablement in the listener editor while making both tuning pages listener-scoped, makes OS diagnostics render only values actually supplied by the current platform, expands external certificate automation, and improves overview/network observability.
## Memory-retention changes
| Requirement | Source implementation | Status |
|---|---|---|
| Bound glibc arena proliferation for managed systemd installs | `deploy/rustproxy.service` and `scripts/deploy.py::service_unit` set `MALLOC_ARENA_MAX=2`; Debian packaging moved to the external packaging repository in 0.27.0, and `/etc/rustproxy/environment` remains the administrator override | implemented in source |
| Avoid a duplicate identity transform buffer | `src/transform/mod.rs::decode` returns `Cow<[u8]>`; identity input is borrowed and compressed input owns only the decoded buffer | implemented in source |
| Reduce JS/CSS minifier peak allocations | `src/transform/js.rs` and `src/transform/css.rs` iterate with `Peekable<Chars>` rather than collecting `Vec<char>`, and return the completed `String` allocation with `into_bytes()` | implemented in source |
| Release temporary transform buffers earlier | successful changed transforms drop the decoded/collected origin buffers before final response construction | implemented in source |
| Give large glibc transform churn a bounded RSS-release opportunity | transformed responses that release at least 256 KiB can call `malloc_trim(0)` no more than once per 30 seconds on Linux GNU targets | implemented in source; sustained-RSS acceptance remains open |
| Keep non-glibc targets portable | allocator-specific tuning/trim code is guarded for Linux GNU; other targets keep the portable allocation path | implemented in source |
`MALLOC_ARENA_MAX=2` is an allocator-tuning default, not an application memory limit. It is useful for this multi-threaded long-running proxy because it limits how many glibc malloc arenas can retain freed pages. It does not replace cache limits, cgroup limits or sustained-load testing.
The cache already calls `malloc_trim(0)` after bulk demotion/purge paths. 0.24.3 does not change cache policy semantics: in particular `cold_on_age` remains an explicit operator choice and defaults to false. This release reduces allocator/transformation retention without silently changing cache freshness or tiering behavior.
## HTTP/2 and HTTP/3 settings placement
Both downstream protocol families now use the named-listener ownership model. `binding.http2` / `binding.h2c` enable HTTP/2, `binding.http2_settings` stores its lifecycle limits, and `binding.http3` is either `null` (disabled) or an object containing QUIC limits. In 0.24.3:
- **Settings -> Listeners** owns the H2, H2C and **Enable HTTP/3 over QUIC (UDP)** switches.
- An H2/H2C listener links to **Settings -> HTTP connections -> HTTP/2**; an enabled H3 listener links to the HTTP/3 page.
- The HTTP/2 page edits idle, absolute-lifetime and graceful-drain limits independently for every H2/H2C listener. The HTTP/3 page continues to edit advertisement, connection, bidirectional/unidirectional stream and idle-timeout limits per enabled TLS listener.
- The legacy top-level `http2` object remains a fallback when an older listener has no explicit `http2_settings`, so existing configurations keep their effective behavior until saved through the new UI.
- Listener/H2/H3 tuning changes remain restart-required. Each tuning page is blocked while the listener form has unsaved changes, preventing stale copies of the listener section from overwriting each other.
## Dynamic diagnostics
The dashboard card is named **Process**. Optional process/system fields are backed by nullable statistics. The browser hides rows and history charts when a field is unavailable on the current platform instead of substituting `unknown`, `N/A` or a synthetic zero. Linux continues to expose its `/proc`/cgroup details; other supported systems show only values supplied by the shared collectors.
The same rule is applied to optional system CPU/RAM/swap/load/uptime and network/latency chart rows where the data source can be absent. This is a presentation change only; the authenticated status API continues to represent unsupported metrics as `null`.
## Certificate automation extensions
| Requirement | Source implementation | Status |
|---|---|---|
| Reload one manual/file-backed certificate after an external file replacement | `POST /api/certificates/{certificate_id}/reload` calls `App::reload_certificate`; ACME-managed IDs are rejected and the configuration revision stays unchanged | implemented in source |
| Permit the same reload through Certificate API authorization | `certificate_api_operation` recognizes the validated per-ID reload path and preserves the external HTTPS/loopback restriction | implemented in source |
| Support multiple independently managed automation tokens | SQLite schema v6 introduces `certificate_api_credentials`, bounded to 32 rows, with Key ID, hash, comment and usage metadata | implemented in source |
| Individual and bulk revocation | `DELETE /api/certificate-api/{key_id}` revokes one; `DELETE /api/certificate-api` revokes all | implemented in source |
| Never persist cleartext automation tokens | PUT returns the clear token once; only SHA-256 hashes and non-secret metadata/comments are stored | implemented in source |
## Dashboard extensions
- **Core State** is replaced by a same-footprint live connection chart for open connections and active exchanges, with backend count retained as chart context. **Uptime** moves to **Process**, directly below process start.
- **Payload transferred** keeps the aggregate value and adds compact download (`bytes_out`) / upload (`bytes_in`) counters.
- Each network-interface chart has a **Hide** action. Hidden interface names are stored only in browser `localStorage` (`rp-hidden-network-interfaces`) and can be restored from the dashboard; no server configuration is changed.
## Open release gates
This workspace does not provide `cargo`, `rustc` or `rustfmt`. Static source, language-pack, JavaScript, shell, Python, deployment/archive and Go-agent gates can run here, but a Rust-enabled release host must still run formatting, `cargo check --locked --all-targets`, `cargo test --locked --all-targets`, a release build, live H2/H3/WebSocket regression and a sustained 10-12 hour cache/transform RSS comparison before production promotion.