Repository navigation
fix(url-util): infer backendUrl from location when behind a path-prefixing proxy - #516
luissilva-mollie wants to merge 1 commit into
Conversation
…ixing proxy Backends that embed the prebuilt adk-web bundle (e.g. adk-java's AdkWebServer) serve runtime-config.json straight out of their own packaged artifact and have no build step to run set-backend.js against, so backendUrl is always "". URLUtil.getApiServerBaseUrl() then falls back to root-relative API calls (GET /list-apps), which breaks behind any reverse proxy that strips a path prefix before forwarding to the backend (e.g. WAP-style routing: /agents/my-agent/* -> container, prefix stripped) — the browser calls the unprefixed path and the proxy 404s. Derive a same-origin default from window.location instead of defaulting to root-relative, preserving whatever prefix this app was itself loaded under. An explicit runtimeConfig.backendUrl still takes precedence, so local dev via set-backend.js is unaffected. Also fixes getBaseUrlWithoutPath(), which hardcoded "/dev-ui/" off the origin and dropped any prefix the same way.
|
Thanks for the detailed write-up and the tests! Since this PR was opened, the dev UI runtime config has moved from a static |
|
Thanks for the explanation, that makes sense, and we've adopted it on the Python side: google-adk 2.11.0 serves A clarification for adk-java: as far as I can tell this isn't supported there yet. In Is a backend-served runtime config planned for adk-java? If so, is there an issue we can follow? If not, we're happy to open one. |
Fixes #515.
Problem
URLUtil.getApiServerBaseUrl()defaults to''(root-relative) whenruntimeConfig.backendUrlisn't configured. That's fine whenadk-webis served at the server root, but breaks any deployment behind a path-prefixing reverse proxy that strips its prefix before forwarding to the backend: the UI loads correctly at e.g./agents/my-agent/dev-ui/, but its API calls go out root-relative (GET /list-apps) and the proxy has no route for that.runtime-config.jsoncan be customized viaset-backend.js, but that only runs at build time against the source tree. Backends that embed an already-builtadk-webbundle as a packaged dependency (e.g.adk-java'sAdkWebServer, servingclasspath:/browser/**out of thegoogle-adk-devjar) have no build step to run it against, and the file is sealed inside a jar at runtime — so there was no way to get a correctbackendUrlin that scenario without patching the frontend.getBaseUrlWithoutPath()(used as the OAuthredirectUri) had the same class of bug: it hardcodesorigin + '/dev-ui/', discarding any prefix.Fix
When
backendUrlisn't explicitly configured, derive a same-origin default fromwindow.locationthat preserves whatever path prefix the app is itself mounted under (by locating/dev-uiinlocation.pathnameand taking everything before it as the mount root), instead of always assuming the API lives at the server root. Applied the same fix togetBaseUrlWithoutPath().An explicit
runtimeConfig.backendUrl(e.g. set viaset-backend.jsfor local dev) still takes precedence, so local dev workflows are unaffected.Refactored the three
URLUtilmethods to accept an optionalLocation-like parameter (defaulting towindow.location) purely for testability —window.locationisn't reconfigurable in a real browser, so this was needed to unit test the new branching without reaching for a more invasive mocking setup.Testing
src/utils/url-util.spec.tscovering both the unprefixed and reverse-proxy-prefixed cases for all three methods, plus the "explicit config wins" case.ng test(full suite): 650 passed, no regressions.ng build: succeeds.