11 KiB
RustProxy 0.31.0 – implementation and verification report
Security/compilation follow-up
- Correct the user-reported
E0716lifetime error in the HTTP BAN/PURGE error path by returning an owned-independent static response and logging the detailed validation error. - Restrict invalidation to the selected HTTP/HTTPS scheme, Host and vhost; reject duplicate maintenance headers, invalid bodies and broad BAN without confirmation. Execute shared cache maintenance in a bounded blocking pool of two operations, rather than scanning on Tokio core workers. Audit authenticated BAN-rule deletion before mutation.
- Add localized BAN/PURGE
curlhelp next to the Cache allowlist and Rust API/auth/security regression tests. Full review, exposure matrix and live test plan: SECURITY_AUDIT_0.31.0. Source-level coverage is not Rust runtime/compile verification.
Panel compression and cache HTTP invalidation follow-up
The 0.31.0 maintenance follow-up introduces one shared, precompressed panel
content handler for authenticated HTML, CSS, JS and language bundles (negotiated
Zstd/Brotli/gzip with identity fallback; settings under Administration), plus
optional IP/CIDR-authorized public BAN/PURGE scoped to the selected vhost.
Existing cache invalidation, revisioned settings and auth/ACL behavior are reused.
The System information Refresh button now sits next to the API badge. See
SETTINGS, CACHE and TEST_REPORT for
behavior and verification limitations. This note does not assert a Rust build.
Date: 2026-10-10. Input: user-provided RustProxy-0.30.1.zip, which does not contain .git metadata. This is a complete edited source snapshot, not a verified checkout of remote master or a compiled/released binary. No commit or tag was created.
Changes implemented
- One dashboard coordinator:
src/admin/web/app/refresh.jsreplaces recurring independent panel timers. Every task has a stable ID, active-view guard, sequentialsetTimeoutscheduling after completion,AbortController, request epoch/generation guards, independent error handling, and manual execution. Auto polling and SSE pause on hidden tabs and stop on logout; timers andvisibilitychangelistener are removed. - SSE with fallback:
/api/events?interval=1|2|5|10preserves one shared live channel per browser with individually selected frequency, session checking and heartbeats. It carries lightweight status and the existing log snapshot./api/status?view=liveand/api/logspolling run only while SSE is unavailable, and are stopped on recovery. The full/api/statusremains available to existing clients. - Traffic / Cache: retained
/api/trafficand/api/cache; they poll only in their active view, while both per-view Auto and account Live switches allow it. The interval comes from per-account preferences.0selects manual operation without disabling refresh buttons, paging, charts, filters or operations. - System diagnostics: new authenticated
/api/system-infosourced from cachedsysinfo/diagnostic and existing ACME-runtime metadata; OS identification is cached. Normal live snapshots no longer include costly system information, memory accounting, certificate runtime details or full configuration. System info polls at the selected lower cadence for Overview and the relevant Settings tabs; manual refresh is always available. - Preferences and UI: existing
/api/preferencesand account-specific SQLite storage extended with defaultedrefreshsettings; strict server/browser allowlists; UI controls, reset, persistence and immediate rescheduling. English/Polish translations maintained. Old preference documents are accepted without migration. - Release: main Cargo manifest/lock package, OpenAPI/version checks and active docs identify
0.31.0. Historical changelog entries and third-party crate version numbers remain intact. Existing SQLite schema 9, cold-cache format 3 and proxy data path are unchanged.
Refresh defaults and boundaries
| Key | Default | Allowed values (seconds) |
|---|---|---|
live_enabled |
true |
true, false |
overview_seconds |
2 | 1, 2, 5, 10 |
traffic_seconds |
5 | 0, 3, 5, 10, 30 |
cache_seconds |
5 | 0, 3, 5, 10, 30 |
system_info_seconds |
60 | 0, 15, 30, 60, 300 |
live_enabled=false pauses all automatic fetching, including SSE and system info. Every manual refresh remains possible. Server stream cadence is client-local, not global. The existing /api/live-logs remains independent, in accordance with its existing logs subscription model.
Verification executed
| Action | Result | Scope/limit |
|---|---|---|
./dev.sh test |
Partial, exit 127 | All Rust-independent preflight, source/module/security/version checks, SQLite schema-9 migration/upgrade, 8 Node UI tests (including new refresh test), docs and language checks passed. Rust toolchain check then failed: cargo/rustc unavailable. |
node tools/checks/refresh_0310_ui_test.mjs |
PASS | Deterministic simulated browser clock: 2/3/5/0-s cadence, manual mode, Live toggle, 20 rapid tab transitions, no duplicate requests/timers, aborting obsolete work, hidden/visible, SSE error/recovery fallback, independent failures, logout/cleanup, browser preference validation. |
go test ./... (in docker-agent/) |
PASS | Go agent unit tests. |
node --check over all src/admin/web/**/*.js |
PASS | JavaScript syntax only, not execution in Chrome/Firefox. |
python3 tools/checks/check_source.py |
PASS | Static contracts (not Rust type checking). |
python3 tools/checks/release_smoke.py |
PASS | Offline SQLite/migration and release integration/source contracts. |
bash -n dev.sh and Python compile checks |
PASS | Shell and Python syntax. |
./dev.sh check, ./dev.sh fmt, ./dev.sh release |
NOT EXECUTED (exit 127) | Rust/Cargo/rustfmt absent. No format, typecheck, Rust unit/integration suite, linked release binary. |
| Live Rust SSE/API/Traffic/Cache + multi-user persistence | NOT EXECUTED | Cannot start the Rust service in this environment. Rust integration regression tests were added to source but not run. |
| Real bandwidth/serialized SSE bytes/CPU, long-running resource metrics | NOT MEASURED | No Rust server. The repo's 2,000 HTTP-request memory-load smoke uses a Python peer, not the RustProxy binary; it is not RustProxy performance evidence. |
Important: all Rust runtime, compile and real end-to-end security, SSE heartbeat/reconnect and production proxy regressions remain open; this source archive cannot be declared production-ready before those checks.
Request-rate analysis (source-derived forecast, not wire measurement)
Rates below are steady-state theoretical at default intervals, for a single visible administrator with no manual clicks; the first fetch after entering a view is extra. They are not byte-size/CPU benchmark results.
| Mode | Previously | v0.31.0 default |
|---|---|---|
| Overview status + logs | ~30 full-status SSE snapshots/min (each contained system data), with log payload | ~30 compact SSE snapshots/min with logs; no concurrent fallback |
| Overview system diagnostics | embedded in each SSE status | ~1 GET /api/system-info/min |
| Traffic active | ~20 GET /api/traffic/min at 3 s |
~12 GET/min at 5 s |
| Cache active | ~20 GET /api/cache/min at 3 s |
~12 GET/min at 5 s |
| Other views / hidden tab | older per-view guard behavior; background SSE not globally paused | zero scheduled Traffic/Cache; hidden tab closes SSE and pauses all automatic polling |
| Settings not requiring diagnostics | independent legacy status data carried by SSE | no automatic GET /api/system-info |
Actual SSE payload lengths, encoding/cost, network traffic and memory footprint must be measured against a running binary. No byte reduction percentage is asserted.
Changed files (40 edited, 8 new, 0 deleted)
AGENTS.mdCHANGELOG.mdCargo.lockCargo.tomlREADME.mdROADMAP.mdSHA256SUMSdev.shdocs/API.mddocs/README.mddocs/SETTINGS.mddocs/TEST_REPORT.mdlangs/en_US.jsonlangs/pl_pl.jsonsrc/admin/documentation/documents.rssrc/admin/logging_api.rssrc/admin/openapi.jsonsrc/admin/preferences.rssrc/admin/router.rssrc/admin/status.rssrc/admin/tests.rssrc/admin/tests/part_04.rssrc/admin/web/acme.jssrc/admin/web/app/core.jssrc/admin/web/app/preferences.jssrc/admin/web/app/runtime.jssrc/admin/web/cache-panel.jssrc/admin/web/docker.jssrc/admin/web/drafts.jssrc/admin/web/index.htmlsrc/admin/web/settings.jssrc/admin/web/traffic-panel.jssrc/admin/web/transform-panel.jstools/checks/check_source.pytools/checks/docs_check.pytools/checks/preflight.pytools/checks/release_smoke.pytools/checks/system_info_0301_ui_test.mjstools/checks/system_info_no_subprocess_contracts.pytools/dev/memory_load.pydocs/IMPLEMENTATION_0.31.0.mdsrc/admin/preferences_columns.rssrc/admin/refresh_preferences.rssrc/admin/status_live.rssrc/admin/status_system.rssrc/admin/tests/part_09.rssrc/admin/web/app/refresh.jstools/checks/refresh_0310_ui_test.mjs
Required remaining release gate
On a host with stable Rust toolchain and a configured development environment, run:
./dev.sh fmt
./dev.sh check
./dev.sh test
./dev.sh release
cd docker-agent && go test ./... && cd ..
Test real session login and per-account persistence, permission denial for /api/system-info, SSE connect/heartbeat/reconnect/disconnect, active-vs-hidden browser polling via DevTools, real /api/status backwards compatibility and live/proxy/cache/traffic behavior. Measure serialized SSE bytes and generation time, CPU and request counts by Overview/Traffic/Cache/Settings/hidden tab. Correct any Rust compilation/runtime failures before deploying or creating a release tag.
Same-version mobile startup follow-up (2026-10-10)
The authenticated dashboard replaces the previous all-body visibility: hidden with a visible CSS-only spinner, a 12-second stalled-start hint with reload link, and an EN/PL explicit failure screen. It reveals the shell and starts the existing refresh coordinator before awaiting noncritical preferences/configuration/status; failed configuration cannot hide the shell. Refresh now is now aligned with the Overview heading. The fixed authenticated HTML is gzip-compressed once into cached bytes, negotiated per request; unchanged identity responses and public login remain. Browser UI/source checks are documented in docs/TEST_REPORT.md; Rust compilation and real wire/mobile tests remain open.