google / google/adk-java

AdkWebServer's root->dev-ui redirect breaks behind a path-stripping reverse proxy

Abierto
#1,457 2 comentarios 0 reacciones 1 asignado Reclamado por @hemasekhar-p Ver en GitHub
needs review
Lenguaje dominante
Java
Estrellas
1.7k
Forks
420
Merge medio
4 d 12 h
PR fusionados (30 d)
31

Descripción

## Description

`AdkWebServer.addViewControllers()` redirects `"/"` to the **root-relative** path `"/dev-ui"`:

https://github.com/google/adk-java/blob/e8b1c20d10680e7ed8e936ae1ac0ab768a0b8345/dev/src/main/java/com/google/adk/web/AdkWebServer.java#L151

```java
registry.addRedirectViewController("/", "/dev-ui");
```

When this app is deployed behind a reverse proxy that strips a path prefix before forwarding the request (a common pattern for platform-managed multi-tenant gateways, e.g. Kubernetes Gateway API `HTTPRoute` with a `URLRewrite`/`ReplacePrefixMatch` filter), the browser follows this redirect to an unprefixed path the proxy has no route for, and the dev UI 404s.

## Why this can't be fixed by the app alone with standard Spring mechanisms

Spring's own reverse-proxy support (`server.forward-headers-strategy=framework`, which installs `ForwardedHeaderFilter`) is specifically designed to solve exactly this class of problem via the `X-Forwarded-Prefix` header — but it only works for **context-relative** redirect targets (ones that do *not* start with `/`). I traced this through `ForwardedHeaderExtractingResponse#sendRedirect`:

```java
path = (path.startsWith(FOLDER_SEPARATOR) ? path :
StringUtils.applyRelativePath(this.request.getRequestURI(), path));
```

Root-relative targets (starting with `/`, as `"/dev-ui"` does) skip the `applyRelativePath` branch entirely — the one place `X-Forwarded-Prefix` awareness would apply — so the prefix is never spliced back in, no matter how the proxy is configured.

## Proposed fix

Change the redirect target to be context-relative instead of root-relative:

```java
registry.addRedirectViewController("/", "dev-ui");
```

I verified this doesn't change behavior for the common local/non-proxied case: `RedirectView`'s `contextRelative` handling only prepends the context path when the target starts with `/` (so a context-relative target like `"dev-ui"` is passed through as-is), and the servlet container's own relative-URL resolution for `sendRedirect` still resolves `"dev-ui"` against the current request path `"/"` to `"/dev-ui"`. It *does* additionally allow `server.forward-headers-strategy=framework` + an `X-Forwarded-Prefix` header to correctly restore a proxy's path prefix, fixing the reverse-proxy case with zero app-specific workaround code.

I've opened a PR with this one-line fix plus the corresponding test update: (link to follow)

## Environment

- adk-java: current `main` (verified against commit `e8b1c20`)
- Encountered while deploying a Java ADK agent behind a Kubernetes Gateway API `HTTPRoute` that strips a per-app path prefix

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.