Repository navigation
fix(live-ws): resolve the public socket URL at runtime - #11377
diegosouzapw merged 1 commit into
Conversation
The browser discovers the Live socket through `/api/v1/ws?handshake=1` precisely because `NEXT_PUBLIC_*` is inlined at build time and a prebuilt Docker or npm image can never carry an operator's value. The server side of that handshake read only the `NEXT_PUBLIC_`-prefixed name, so it had nothing to echo: behind a reverse proxy the dashboard kept dialling `wss://<host>:20132/live-ws` and sat on "Live disabled". `resolveLiveWsPublicUrl` reads `LIVE_WS_PUBLIC_URL` at runtime, alongside the existing runtime `LIVE_WS_HOST` / `LIVE_WS_PORT`, and keeps the prefixed name as the fallback so deployments already setting it are unaffected. Only `ws://` and `wss://` are accepted, matching the guard the client already applies, and the derived path follows the URL. Fixes cheaper-inference#11331
|
CI note, so the red is not left ambiguous.
The same assertion fails identically on #11374, #11376, #11377 and #11380, whose
I have not touched the coverage floor: rebaselining a gate I did not break is not |
9f30b76
into
cheaper-inference:release/v3.8.50
…ence#11377) Merged via consolidated batch validation. Fixes live-ws public socket URL resolution for prebuilt Docker/npm images, where NEXT_PUBLIC_* is inlined at build time and can never carry an operator's runtime value. Own test passes.
Fixes #11331.
release/v3.8.50is not green; the failures this PRinherits are the ones tracked there, not introduced here.
Root cause
The runtime-discovery path already exists and is there for exactly this deployment:
the browser reads
/api/v1/ws?handshake=1becauseNEXT_PUBLIC_*is inlined atbuild time, so a prebuilt Docker/npm image can never carry an operator's value.
useLiveDashboard.tssays so in its own comment.But the server side of that handshake resolved the URL like this:
so in a prebuilt image it had nothing to echo. The client then fell through to
getDefaultWsUrl(), which hardcodes:20132— the reporter'swss://omniroute.domain.tld:20132/live-ws, unreachable behind Traefik, and the UIsits on "Live disabled — WebSocket disconnected. Showing last known state."
LIVE_WS_HOST/LIVE_WS_PORTare read at runtime (seeresolveEmbedWsHost),which is why setting them looked like it should have worked.
Change
resolveLiveWsPublicUrl(env)insrc/shared/utils/wsPath.ts, next toderiveLiveWsPath:LIVE_WS_PUBLIC_URLat runtime — the un-prefixed name, consistent withLIVE_WS_HOST/LIVE_WS_PORT;NEXT_PUBLIC_LIVE_WS_PUBLIC_URLas the fallback, so any deployment alreadysetting it is unaffected;
ws:///wss://, the same guardsanitizeWsPublicUrlapplies onthe client, and trims surrounding whitespace;
getLiveWsPath()derives from the resolved value, so a proxy path like/omniroute/livereaches the client through the handshake too.The handshake route now calls it. The hardcoded
:20132default is untouched —it is still correct when no public URL is declared, and changing it to same-origin
would need an upgrade handler on the HTTP port that
src/proxy.tsdoes not have(the comment in
getDefaultWsUrlrecords why that was tried and reverted).Tests
tests/unit/live-ws-public-url-11331.test.ts(new, 7 cases): the runtime namehonoured; the prefixed name still working and losing to the runtime one; non-ws
schemes rejected (
https://,javascript:, barehost:443); blank/whitespacefalling through to the next candidate; surrounding whitespace trimmed rather than
rejected; the path following the resolved URL; and a source assertion that the
handshake route no longer reads the build-time-only name directly.
Mutation check — restoring the route's old body fails exactly:
The three existing live-ws suites (
instrumentation-live-ws,live-ws-cookie-parse,live-ws-eaddrinuse-6324) stay green.npx tsc --noEmitclean; eslint clean withthe repo's suppressions file.
Changelog fragment:
changelog.d/fixes/live-ws-public-url-runtime.md.