google / google/adk-java

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

オープン
#1,457 コメント 2 件 リアクション 0 件 担当者 1 名 @hemasekhar-p が担当を希望しています GitHub で見る
needs review
主要言語
Java
スター
1.7k
フォーク
420
平均マージ
4日 12時間
マージ済み PR(30日)
31

説明

## 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

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。