153 lines
11 KiB
Markdown
153 lines
11 KiB
Markdown
# RustProxy 0.31.0 – implementation and verification report
|
||
|
||
### Security/compilation follow-up
|
||
|
||
- Correct the user-reported `E0716` lifetime 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 `curl` help 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](SECURITY_AUDIT_0.31.0.md). 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](SETTINGS.md), [CACHE](CACHE.md) and [TEST_REPORT](TEST_REPORT.md) 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
|
||
|
||
1. **One dashboard coordinator:** `src/admin/web/app/refresh.js` replaces recurring independent panel timers. Every task has a stable ID, active-view guard, sequential `setTimeout` scheduling 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 and `visibilitychange` listener are removed.
|
||
2. **SSE with fallback:** `/api/events?interval=1|2|5|10` preserves 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=live` and `/api/logs` polling run only while SSE is unavailable, and are stopped on recovery. The full `/api/status` remains available to existing clients.
|
||
3. **Traffic / Cache:** retained `/api/traffic` and `/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. `0` selects manual operation without disabling refresh buttons, paging, charts, filters or operations.
|
||
4. **System diagnostics:** new authenticated `/api/system-info` sourced from cached `sysinfo`/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.
|
||
5. **Preferences and UI:** existing `/api/preferences` and account-specific SQLite storage extended with defaulted `refresh` settings; strict server/browser allowlists; UI controls, reset, persistence and immediate rescheduling. English/Polish translations maintained. Old preference documents are accepted without migration.
|
||
6. **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.md`
|
||
- `CHANGELOG.md`
|
||
- `Cargo.lock`
|
||
- `Cargo.toml`
|
||
- `README.md`
|
||
- `ROADMAP.md`
|
||
- `SHA256SUMS`
|
||
- `dev.sh`
|
||
- `docs/API.md`
|
||
- `docs/README.md`
|
||
- `docs/SETTINGS.md`
|
||
- `docs/TEST_REPORT.md`
|
||
- `langs/en_US.json`
|
||
- `langs/pl_pl.json`
|
||
- `src/admin/documentation/documents.rs`
|
||
- `src/admin/logging_api.rs`
|
||
- `src/admin/openapi.json`
|
||
- `src/admin/preferences.rs`
|
||
- `src/admin/router.rs`
|
||
- `src/admin/status.rs`
|
||
- `src/admin/tests.rs`
|
||
- `src/admin/tests/part_04.rs`
|
||
- `src/admin/web/acme.js`
|
||
- `src/admin/web/app/core.js`
|
||
- `src/admin/web/app/preferences.js`
|
||
- `src/admin/web/app/runtime.js`
|
||
- `src/admin/web/cache-panel.js`
|
||
- `src/admin/web/docker.js`
|
||
- `src/admin/web/drafts.js`
|
||
- `src/admin/web/index.html`
|
||
- `src/admin/web/settings.js`
|
||
- `src/admin/web/traffic-panel.js`
|
||
- `src/admin/web/transform-panel.js`
|
||
- `tools/checks/check_source.py`
|
||
- `tools/checks/docs_check.py`
|
||
- `tools/checks/preflight.py`
|
||
- `tools/checks/release_smoke.py`
|
||
- `tools/checks/system_info_0301_ui_test.mjs`
|
||
- `tools/checks/system_info_no_subprocess_contracts.py`
|
||
- `tools/dev/memory_load.py`
|
||
- `docs/IMPLEMENTATION_0.31.0.md`
|
||
- `src/admin/preferences_columns.rs`
|
||
- `src/admin/refresh_preferences.rs`
|
||
- `src/admin/status_live.rs`
|
||
- `src/admin/status_system.rs`
|
||
- `src/admin/tests/part_09.rs`
|
||
- `src/admin/web/app/refresh.js`
|
||
- `tools/checks/refresh_0310_ui_test.mjs`
|
||
|
||
## Required remaining release gate
|
||
|
||
On a host with stable Rust toolchain and a configured development environment, run:
|
||
|
||
```sh
|
||
./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.
|