google / google/adk-java

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

Đang mở
#1,457 2 bình luận 0 reaction 1 người được giao Được @hemasekhar-p nhận Xem trên GitHub
needs review
Ngôn ngữ chính
Java
Star
1.7k
Fork
420
Merge trung bình
4 ngày 12 giờ
Pull request đã merge (30 ngày)
31

Mô tả

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

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.