Files
RustProxy/docs/IMPLEMENTATION_0.31.1.md
T
2026-10-10 21:48:39 +02:00

3.5 KiB

RustProxy 0.31.1 — mobile dashboard initialization

Scope

This patch changes only the authenticated administration panel bootstrap and its release documentation. It does not modify reverse-proxy traffic processing, authentication, stored configuration, SQLite migrations or preference values.

Root-cause analysis

Previously, the authenticated dashboard HTML requested 17 independent deferred JavaScript files. The first one (/assets/app.js) starts asynchronous session and configuration requests from web/app/runtime.js. Deferred ordering only orders script evaluation, not asynchronous continuation: a completed API call can resume while later JavaScript resources are still downloading. In that window, a render path may access window.rustProxyIntegrations.bindings before integrations.js has finished evaluating. The browser then reports an undefined-object exception. A failed/missing script has the same symptom.

The reported iPhone/reverse-proxy incident is consistent with this race. It was not possible to capture the user's mobile network trace, so the precise combination of mobile transport behavior, timing, and content encodings is not proven.

Changes

  1. The dashboard HTML now requests only /assets/app.js?v=0.31.1. On the backend, the same existing /assets/app.js route assembles all existing UI source modules in their prior load order. /assets/vhosts.js and the other private asset URLs remain available for compatibility.
  2. Startup waits for DOMContentLoaded and verifies the required modules before requesting a session or configuration. A missing module produces a visible startup failure with the existing retry link instead of a partially initialized workspace.
  3. Authenticated HTML also requests /assets/style.css?v=0.31.1; versioned URLs separate release assets in intermediary caches. No cache bypass or potentially unsafe public caching is introduced on the server.
  4. The initial /api/config load retries at most twice after a transient failure (400 ms / 800 ms delays). If it cannot load, the existing startup recovery UI is displayed. Session rejection (401) does not trigger retries.
  5. Public login, CSP, compression negotiation, SSE, polling, Traffic and Cache APIs, user preferences and the proxy request path are unchanged.

Acceptance checks

  • Node.js parses each source module and the complete emitted dashboard bundle.
  • A JavaScript startup test verifies zero API requests before DOM readiness, successful activation with complete modules, and recovery when a module is missing. A second test verifies configuration retry success/failure.
  • Chromium smoke test on the authenticated HTML with simulated session and configuration endpoints, at desktop and mobile widths, when available.
  • Run ./dev.sh test and ./dev.sh check in an environment with Rust/Cargo.
  • On the production reverse-proxy path, test initial load, 20+ rapid reloads, navigation between tabs, Safari on iPhone (Wi-Fi and cellular), and a deliberately delayed/failed /api/config response. Confirm no uncaught JS errors and no mixed asset versions.
  • Compare actual HTTP Content-Encoding, Content-Length, Vary, Status and response bodies for document, script and stylesheet behind the reverse. Disable any reverse cache rule that ignores version/query keys.

Environment limitations

Compiler/type-checking, live RustProxy API tests and Safari/iPhone tests require the target runtime; they cannot be inferred from source or Chromium alone.