Files
RustProxy/docs/V0.24.3_AUDIT.md
T
2026-10-03 00:27:09 +01:00

6.4 KiB

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, debian/rustproxy.service and scripts/deploy.py::service_unit set MALLOC_ARENA_MAX=2; /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.