23 KiB
Verification report - RustProxy 0.30.0
0.30.0 same-version sustained-memory audit (2026-10-10)
- Reviewed cache metadata, HOT/COLD admission and cleanup, file/remote JSON sinks, live log history, analytics, local directory listings, HTTP/2/HTTP/3, TCP/UDP sessions, DNS/health tasks, PHP-FPM streaming, transforms, rate-limit buckets, and periodic tasks. See memory verification for audited invariants and the real-runtime acceptance procedure.
- Confirmed a long-run retention issue: the selective PURGE path incremented
Store.key_generationsfor affected base keys and never reclaimed those identities until an all-cache purge. Its existing globalgenerationbarrier already invalidates all older fills/tickets, so obsolete per-key metadata can be reset per selective PURGE. Also release large HashMap capacity after mass invalidations. Added a 512-distinct-PURGE Rust regression (not executed without Cargo). - Removed unnecessary repeated analytics-label allocations using borrowed map lookups and allocation on insertion only. Filtered local directory listings in place rather than building a second metadata vector and moved generated HTML into the response instead of cloning it. Reused the existing redacted JSONL serialization when sending the same access event to Loki (while preserving the Loki-only path).
- Offline test: 300,000 simulated distinct PURGE identities over six intervals. Legacy bookkeeping model retained 50k → 300k keys, whereas the corrected epoch model retained 1 key after each operation. The load driver sent 10,000 real HTTP requests using 24 persistent clients and 1,000 distinct paths to a Python test peer, with expected status/body counts. These tests validate model behavior and driver operation only: they do not measure RustProxy RSS, heap, or leak freedom.
./dev.sh test: all Rust-independent source, security, SQL/upgrade, Node/browser UI, documentation/translation and memory-replay checks passed (including its 2,000-request peer smoke); exit 127 only at the missing Cargo toolchain guard../dev.sh checkalso exits 127 for missing Cargo.go test ./...indocker-agentpassed.- Rust/Cargo unavailable in this environment. Actual
cargo check, Rust unit tests, RustProxy GET/PURGE under load, production-like JSON sinks, HTTP/2/3 and TCP/UDP traffic, and long-duration RSS/heap plateau measurements remain pending. No API, SQLite schema, Cold Cache format or version changes.
0.30.0 source verification (2026-10-10)
- Moved per-backend health-check overrides into the Health tab: a monitored-only backend selector reveals one persistent editor at a time, without changing the JSON configuration schema. Newly enabled custom policies start from the current shared policy; previously customized backends keep their configured values. Disabling monitor hides the editor but retains the override. Preserving draft switching, validation routing, rename and removal is covered by the simulated DOM regression.
- Memory audit: access-file JSONL and Logstash now share one serialization for each event. Existing bounded file/error sink queues, live history, open files, traffic analytics and cache/transform budgets were checked in source. Removed two avoidable directory-inventory memory spikes: per-vhost log scanning now retains at most 256 candidates while enumerating and gzip-rotation scanning at most 64. Added a source contract and a Rust unit regression for 10,000 candidate filenames and deterministic newest-first ties.
- The Node/UI, source, security, upgrade, SQL migration, translation and documentation checks in
./dev.sh testare run in this environment; the Rust suite and full./dev.sh checkcannot complete becausecargoandrustcare unavailable (exit 127).go test ./...indocker-agentis run separately. The Rust unit regression is included but not executed. No real request-load test or long-running RSS/heap profile was performed, so the review cannot prove complete absence of runtime leaks. - No SQLite schema migration or Cold Cache format change; root Cargo package/lock and OpenAPI version set to
0.30.0. Use a Rust toolchain for./dev.sh checkand./dev.sh test, and measure RSS during sustained file/JSON logging, before deploying.
Same-version 0.29.7 PHP profile UI, Rust warning and error interception review (2026-10-09)
- Move the shared PHP-FPM Syntax and safety help button to the bottom of the profile-management dialog, below Add profile, with a visible horizontal separator. Keep the service-local help button where it was. The simulated Web Service UI test asserts this placement and that the help modal still opens.
- Remove the unused
mutin theweb_server::servebinding (src/proxy/forward/web_source.rs). - Correct application-error interception semantics in both Reverse Proxy and Web Server/PHP-FPM: responses supplied by a backend/service (including cache hits) are explicitly marked and are not overwritten by global/vhost error pages when
pages.intercept_statusesis disabled. RustProxy-generated routing/upstream failures remain eligible for the configured local error page. Interception is performed before cache admission; selected statuses receiveno-storeeven after response-header rules and always retain the application's HTTP status, ignoring a standalone error page's status override. An internal named-location fallback remains terminal and has precedence. - Rust regression tests cover the opt-in behavior, the marker's effect in the response observer, precedence and preservation of status with a differently configured page status. Source/UI contracts verify both forwarding paths and correct ordering around HTTP/2 WebSocket body adaptation; these are not substitutes for live protocol tests.
./dev.sh test: all Rust-independent source, JS, SQL/upgrade, security, documentation and translation checks passed; then exited 127 due to unavailablecargo/rustc. Rust compilation, unit tests and runtime HTTP/FastCGI/WebSocket acceptance have not been performed here. No configuration schema change or version bump.
0.29.7 same-version compile error corrections (2026-10-09)
- Correct the three operator-reported
E0308mismatches. Reverse Proxy origin interception now receives anaxum::body::Bodyresponse only after adapting the upstreamResponse<hyper::body::Incoming>, preserving the originalIncomingbody expected by the HTTP/2 WebSocket tunnel wrapper. The operation remains before transformation and cache admission. - Reapply configured response-header rules to an intercepted page, then restore
Cache-Control: no-storeso the admin page cannot accidentally enter shared cache through a custom header policy. Internal named error fallbacks retain precedence. - Build owned
Arc<Member>candidates for the active health-check supervisor and clone theArcinto eachJoinSet::spawntask, rather than attempting to spawn a future carrying&Arc<Member>. - Static/UI/source/SQL/upgrade/security/documentation checks passed via
./dev.sh testup to the Rust guard (exit 127)../dev.sh checkexited 127 before compilation due to missing Rust/Cargo. These are source-level corrections, not a verified Rust build. Operator should run./dev.sh checkand./dev.sh teston a Cargo-equipped host before deployment.
0.29.7 in-version PHP UX and origin error interception (2026-10-09)
- Both Web Service local PHP fields and shared PHP-FPM profiles now expose per-field examples, units, bounded syntax, PATH_INFO/Authorization/PHP enablement info tooltips and a common detailed help dialog; all localized through language packs. Configuration semantics remain unchanged.
- New optional
vhosts[].pages.intercept_statuses: supported unique HTTP error codes are validated; selected application-origin responses are replaced by vhost/global/built-in RustProxy pages before admission to cache, preserve the HTTP status by default, and carryCache-Control: no-store. The existing internal error fallback runs first. Empty/default list leaves existing origin error responses intact. - Added Rust source-level regression tests for default preservation, replacement, headers, precedence and malformed codes plus JS form behavior checks.
./dev.sh testran all pre-Cargo contracts (including Web Service PHP profile editing, origin-interception roundtrip, offline migration and security checks) successfully but exited 127 at the missingcargoguard../dev.sh checkalso exited 127 for that reason. Rust compilation, Rust unit execution, and live Web Server/FastCGI/backend routing remain unverified.
0.29.7 backend/cache/FPM policy review (2026-10-09)
- Backend monitoring now has an explicit per-member switch and optional policy; tests cover backwards-compatible defaults, serialization, inherited Host and validation. Membership in the balanced pool remains a separate setting.
cache.expose_only_hitsdefaults to false globally and may be overridden at a vhost. Tests cover HIT/MISS/BYPASS suppression, origin diagnostic removal, independently configured Via and cache identity stability. Actual wire behavior requires Cargo/runtime tests.- PHP limitation: user-supplied WordPress and Roundcube services both target
unix:/run/php/php_rustproxy.sock. Only Roundcube passes a restrictive FastCGIPHP_ADMIN_VALUE: open_basedir; PHP-FPM may retain this value across worker reuse, causing WordPress to fail. The 302 to setup-config.php is a consequence of missing access to wp-config.php. Added conflict warning, inline guidance and pool-isolation instructions; code changes cannot alter an already-shared PHP-FPM worker's isolation. The operator must provision and select a dedicated Roundcube FPM pool and restart/recycle affected old workers. - Source changes keep SQLite schema 9/Cold Cache format 3. Compiler-independent tests and verification are reported below; Rust compilation/live HTTP/2/H3/PHP integration is not asserted in this environment.
0.29.7 verification summary
./dev.sh test: all Rust-independent contracts, SQLite migration/backup/source-upgrade checks, JS vhost/Web Server regressions, source security/dependency audits, docs and translation checks passed. It exits with code 127 at the Rust/Cargo availability guard, becauserustcandcargoare not installed. This is not a successful Rust test-suite run.node tools/checks/backend_cache_0297_ui_test.mjs: passed; simulates the actual backend form toggles and verifies independent monitoring/pool-eligibility state, per-member health override and cache controls.- Rust-only regression tests were added but could not execute: effective active/passive member policies and validation, HTTP Host defaults, HIT-only cache headers, per-vhost policy resolution, and cache compatibility identity.
- Operator acceptance remains open: Rust compilation, real PHP-FPM worker isolation on separate sockets, alternating WordPress/Roundcube requests, live 404 fallback, and actual wire-level cache HIT/MISS/BYPASS checks on HTTP/1.1, H2 and H3.
0.29.6 FastCGI EOF and error-log routing (2026-10-09)
- Operator reproduced: uncompressed
/static.php/...returned HTTP 200 and 29,309 bytes with cache BYPASS; gzip returned HTTP 200 then TLS unexpected EOF and zero bytes. Repeated panics infutures-util 0.3.34stream/unfold.rs:108correlate with these failures. This is operator evidence, not a reproduced in-house integration test. - Cause identified in source: native Web Server FastCGI response bodies used an unfused
stream::unfoldover a Tokio MPSC receiver. The compression wrapper may poll the stream after it returnsNone; the unfusedUnfoldthen panics. The Reverse Proxy source uses an HTTP client body rather than this FastCGI stream. - Change: wrap the FastCGI response stream in
.fuse(). Add repeated-post-EOF polling test and mocked FastCGI-to-gzip completion/decode test. No changes to PHP-FPM parameters, vhost configuration or migrations. - Logging change: the existing error-file controller receives WARN and ERROR (including PHP-FPM stderr); the console tracing layer suppresses these only when the file is enabled, with fallback to stderr on file/queue failure. A Rust panic hook emits structured ERROR diagnostics instead of bypassing the sink via the default stderr hook.
- Add asynchronous file routing and live enabled/disabled toggle tests. Actual Rust compilation, FastCGI compressor tests, panic runtime acceptance and live Roundcube regression require a Cargo-equipped environment and remain unverified here.
- Release: Cargo package/lock root/OpenAPI and release checks moved to 0.29.6; retained SQLite schema 9 and Cold Cache format 3.
- Static checks passed:
version_contracts.py,docs_check.py,langs_check.py,rust_module_contracts.py,web_server_contracts.py,check_source.py,release_smoke.py,web_service_ui_test.mjs, and Node syntax/OpenAPI JSON parsing. The./dev.sh testrun passed its source, browser UI, security, memory and upgrade checks before reaching the missing Rust toolchain;./dev.sh checkexited 127 for the same reason.
0.29.5 Roundcube PHP PATH_INFO dispatch (2026-10-09)
- Cause confirmed by source:
serve_inneroriginally rantry_filesbefore recognizing/static.php/skins/...as a PHP script plusPATH_INFO. For an existingstatic.php, the lasttry_filescandidate/index.phpintercepted the asset request and could return HTML instead of the asset. - Fixed dispatch order following rewrites and path ACLs; execute existing PHP PATH_INFO targets before
try_files. Access restrictions also apply to the resolved PHP script path; the other fallback path remains protected. - Added
roundcube_static_php_path_info_runs_before_front_controller_try_filesandwithout_php_path_info_try_files_keeps_legacy_front_controller_fallbackusing a local test FastCGI server and decoded FastCGI params. These are source tests until run with Cargo, not validated against live PHP-FPM or Roundcube. - Operator action: ensure PHP-FPM PATH_INFO splitting enabled on the chosen Web Service / shared profile; keep
try_filesfor the main service. No extra special-case URL rewrite is needed for Roundcubestatic.phpURLs. - Static checks passed:
version_contracts.py,web_server_contracts.py,rust_module_contracts.py,docs_check.py,langs_check.py,web_service_ui_test.mjs, andrelease_smoke.py../dev.sh testexceeded the available execution limit while running broader staticcheck_source.py.cargo/rustcare unavailable; the new Rust FastCGI tests were not executed and neither was a live Roundcube integration.
0.29.4 PHP-FPM profile toolbar shortcut (2026-10-09)
The Web Server list toolbar now contains a PHP-FPM profiles button immediately before New Web Service. Both this shortcut and the PHP tab's existing profile button open the same shared profile-management dialog; no API or configuration schema changes were required. English/Polish button translations and a UI regression covering placement, both entry paths and closing the dialog were added.
node --check on the changed Web Server script and its profile helper,
node tools/checks/web_service_ui_test.mjs, and the focused version,
language, Web Server architecture and documentation checks passed.
./dev.sh test was attempted but exceeded the execution time limit during
the Rust-independent verification phase, so it did not complete in this run.
Rust compilation and runtime tests remain unverified without Cargo.
0.29.4 version bump (2026-10-09)
The PHP-FPM profiles, Web Server cache/transforms and HTTP_HOST fixes have
been assigned to a new 0.29.4 release. The source version, root Cargo.lock
package entry, OpenAPI metadata, release checks and documentation match 0.29.4.
The 0.29.3 internal-fallback changes remain included. This is a source release;
no compiled artifacts are included.
Release verification: python3 tools/checks/version_contracts.py,
python3 tools/checks/check_source.py, python3 tools/checks/docs_check.py,
python3 tools/checks/release_smoke.py and the Node Web Service profile
UI regression checks passed. ./dev.sh test completed its Rust-independent
source, migration/upgrade, security, browser and documentation checks, then
exited 127 because Rust/Cargo is not installed. Compilation, Rust unit tests
and live HTTP/FastCGI/cache/transform verification remain unperformed.
0.29.4 feature verification (2026-10-09)
The operator-requested follow-up adds reusable PHP-FPM profiles, fixes the
Web Server cache/transform bypass and supplies HTTP_HOST for authority-only
HTTP/2 and HTTP/3 FastCGI requests. Changes include Config serialization,
revisioned administration section and OpenAPI, Web Server browser modal,
route cache/transform pipeline and FastCGI parameter encoding. New Rust unit
tests cover profile resolution, detach, validation and HTTP_HOST; the Node UI
test exercises opening/editing a profile and attaching it to a service.
Rust compilation, proxy/PHP-FPM integration tests and performance acceptance remain unverified without Rust/Cargo. Static contracts and browser tests are run separately and do not substitute for production acceptance.
Changes
0.29.3 fallback correction (operator report): the replay-body guard treated HTTP/2 and HTTP/3 GET/HEAD bodies with unknown size hints as non-replayable, even when the stream was empty. The fallback guard now performs the existing bounded empty-body probe for GET/HEAD; a true empty stream is replayable, while nonempty/unknown-length request bodies are forwarded only once. The internal target lookup now warns when the named location cannot be resolved. Added Rust async regression tests for empty H2/H3 GET/HEAD, unknown-length GET payload preservation, and unbounded POST non-consumption. The observer also preserves the final internal fallback response (including its 404 HTML) instead of applying a second global/vhost error page; a Rust test exercises this precedence. These Rust tests have not been executed in this environment because Cargo is unavailable.
Same-version 0.29.2 correction: Web Server main routes no longer inherit transient_unavailable from the vhost backend configuration. When the Web Server source has no enabled Reverse Proxy Custom Locations, backend definitions are not compiled. An enabled reverse-proxy Custom Location still compiles and uses the backend pool. Removed fallback-only Prometheus metrics, retained PHP/Web Server metrics.
Validated operator-controlled PHP_ADMIN_VALUE FastCGI configuration per Web Service, with distinct PHP_VALUE/ADMIN directive sets, explicit panel controls and OpenAPI schema. Prometheus PHP Web Service request/status counters, response header latency and available concurrency permit gauge, plus Web Server service-scoped response statuses and header latency.
Acceptance limitations
The build environment has no Rust compiler (cargo/rustc). Rust compilation,
unit tests, FastCGI integration with a live PHP-FPM pool and runtime load tests
have not been performed here. Rust-independent checks are recorded separately.
This source package is not certified for production deployment.
Checks performed
-
0.29.3 release identity:
Cargo.toml, the rootrust-proxyentry inCargo.lock, administration OpenAPI version, README, CHANGELOG, ROADMAP, AGENTS and verification-report heading were updated to 0.29.3; the fallback source changes from the tested 0.29.2 correction are retained. -
0.29.3 offline validation:
python3 tools/checks/version_contracts.py,python3 tools/checks/check_source.py,python3 tools/checks/release_smoke.pypassed;bash ./dev.sh testpassed all listed non-Rust checks and stopped at missing Cargo with exit 127. This does not constitute compilation or successful runtime testing of RustProxy 0.29.3. -
Fallback correction:
bash ./dev.sh testpassed Rust-independent module, source, upgrade/SQLite, security, browser UI and documentation checks. It exited 127 at the missing Rust/Cargo toolchain.bash ./dev.sh checkalso exited 127 because Rust/Cargo is unavailable. The added Rust regression tests and the live HTTP/2/HTTP/3 proxy behavior remain unverified pending a compiler-enabled runtime and an operator test againstorigin-1/origin-2. -
Same-version correction:
python3 tools/checks/check_source.pyandpython3 tools/checks/release_smoke.pypassed.bash ./dev.sh testpassed the Rust-independent checks and stopped at missing Rust/Cargo (exit 127). No live 503 regression test or Rust compilation could be performed. -
./dev.sh test: all Rust-independent release, upgrade, security, JS, UI, documentation and source checks passed; exited 127 at the missingcargotoolchain guard. -
node --check src/admin/web/web-server.js: passed. -
python -m json.tool src/admin/openapi.json: passed. -
./dev.sh check: exited 127 because Rust/Cargo is unavailable.
Debian deployment maintenance (same 0.29.2)
Installer/update now installs /etc/logrotate.d/rustproxy using the recorded service user/group. Updates repair /etc/profile.d/rustproxy-path.sh rather than warning. logrotate uses copytruncate because RustProxy holds open log descriptors; some log records may be lost during truncate. Rust build and live Debian/systemd acceptance remain unverified in this environment.
Version identity (0.29.7 source release)
Cargo.toml package version is the canonical release identity (now 0.29.7). Rust uses CARGO_PKG_VERSION at build time; build.rs substitutes the admin HTML placeholder. Packaging, upgrade and dev scripts read the manifest with scripts/version.py. Run python3 tools/checks/version_contracts.py to check that executable paths do not hardcode a version. Historical documentation and external dashboards may retain manually managed versions. Rust compilation/runtime verification is still pending.
Shared PHP-FPM profiles and Web Server cache/transform/Host patch (0.29.4)
- Added a revisioned
php_fpm_profilescollection with per-Web-Servicephp_profile_id, preserving the local PHP configuration when a shared profile is attached/detached. Added profile editor modal, schema, Polish/English messages and browser regression test. - Web Server vhost/location responses now pass the configured RustProxy cache, vhost response rules and transforms. Cache skips ineligible/private/
Set-Cookieresponses and handles cache hits, conditional requests and range requests. Filesystem/PHP requests are refreshed synchronously rather than using the reverse-proxy background revalidator. - FastCGI always supplies
HTTP_HOSTwhen HTTP/2 or HTTP/3 omitted the ordinaryHostheader; existing explicit Host with port is retained. Added Rust regression tests for both paths. bash ./dev.sh test: all Rust-independent release, source, security, browser UI, documentation, migration and dependency checks passed; stopped at absent Rust/Cargo (exit 127).bash ./dev.sh checkalso stopped at absent Cargo (exit 127). Rust compilation, new Rust tests and live PHP-FPM/HTTP2/HTTP3 cache/transform verification remain unverified in this environment.