Skip to content

fix(http): honor X-Forwarded-Prefix when proxy strips the prefix#9614

Open
Dennisadira wants to merge 1 commit intomudler:masterfrom
Dennisadira:fix/x-forwarded-prefix-asset-urls
Open

fix(http): honor X-Forwarded-Prefix when proxy strips the prefix#9614
Dennisadira wants to merge 1 commit intomudler:masterfrom
Dennisadira:fix/x-forwarded-prefix-asset-urls

Conversation

@Dennisadira
Copy link
Copy Markdown
Contributor

Summary

Closes #9145.

The React UI failed to load when LocalAI was exposed through a reverse proxy that strips the matched path prefix before forwarding (e.g. Caddy's handle_path /localai/*). Two issues combined to break this:

  1. BaseURL ignored X-Forwarded-Prefix when StripPathPrefix had nothing to strip. It only computed a prefix from the request path the middleware had rewritten, so when the proxy already stripped the prefix upstream the base URL came back without one. Extracted a BasePathPrefix(c) helper and added an X-Forwarded-Prefix header fallback so the prefix is recovered in either flow.
  2. Even with <base href> correct, path-absolute references bypass it. Per the HTML spec, URLs starting with / resolve against the base origin, not the base path, so the ="/assets/..." and ="/favicon.svg" references emitted by the build went straight to the origin and bypassed the proxy prefix. serveIndex now rewrites those references to include the prefix when one is present.

Test plan

  • go test ./core/http/middleware/... — 19/19 specs pass, including new BaseURL cases for the pre-stripped path scenario (with and without trailing slash on the header).
  • New integration test in core/http/app_test.go asserts both <base href> and asset URLs are correct when the prefix arrives only via X-Forwarded-Prefix.
  • Manual verification behind Caddy handle_path with the reproducer from X-Forwarded-Prefix no longer works #9145.

🤖 Generated with Claude Code

Closes mudler#9145.

Two related issues kept the React UI from loading when a reverse proxy
rewrites a sub-path with prefix-stripping (e.g. Caddy `handle_path`):

1. `BaseURL` only computed a prefix from the path StripPathPrefix had
   removed, so when the proxy strips the prefix before forwarding, the
   request arrives without it and the base URL was returned without a
   prefix. Extract a `BasePathPrefix` helper and add an
   `X-Forwarded-Prefix` header fallback so the prefix is recovered.
2. `<base href>` only changes how relative URLs resolve; the build
   emits path-absolute references like `/assets/...` and
   `/favicon.svg`, which still resolve against the origin and bypass
   the proxy prefix. Rewrite those references in the served
   `index.html` so the browser requests them through the proxy.

Adds unit coverage for `BaseURL` with a pre-stripped path and an
end-to-end test for the proxy-stripped scenario.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

X-Forwarded-Prefix no longer works

1 participant