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
- The dashboard HTML now requests only
/assets/app.js?v=0.31.1. On the backend, the same existing/assets/app.jsroute assembles all existing UI source modules in their prior load order./assets/vhosts.jsand the other private asset URLs remain available for compatibility. - Startup waits for
DOMContentLoadedand 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. - 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. - The initial
/api/configload 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. - 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 testand./dev.sh checkin 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/configresponse. Confirm no uncaught JS errors and no mixed asset versions. - Compare actual HTTP
Content-Encoding,Content-Length,Vary,Statusand 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.