Skip to content

fix: add ROOT_PATH_SKIP_PREFIXES to exempt sibling-service links from root_path rewriting#195

Closed
lhoupert wants to merge 2 commits into
developmentseed:mainfrom
lhoupert:fix/scope-root-path-link-rewrite
Closed

fix: add ROOT_PATH_SKIP_PREFIXES to exempt sibling-service links from root_path rewriting#195
lhoupert wants to merge 2 commits into
developmentseed:mainfrom
lhoupert:fix/scope-root-path-link-rewrite

Conversation

@lhoupert

@lhoupert lhoupert commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

closes #196

🤖 Claude text below 🤖

On shared-host deployments (e.g. eoapi-k8s defaults: this proxy at /stac with titiler at /raster, /vector, /browser on the same hostname), STAC items carry same-host links to sibling services (rel=xyz, tilejson, viewer, ...). ProcessLinksMiddleware prepends ROOT_PATH to every same-host link, so https://host/raster/... is served as https://host/stac/raster/... → 404. Netloc can't disambiguate these: with OVERRIDE_HOST=false the upstream honours forwarded headers and generates its own links with the request netloc too, and those must keep getting ROOT_PATH (per test_transform_with_forwarded_headers).

This adds an opt-in ROOT_PATH_SKIP_PREFIXES setting (comma-separated path prefixes, e.g. /raster,/vector,/browser): same-host links whose path matches a configured prefix are left untouched. Matching is path-segment-aware (/raster matches /raster and /raster/..., not /rasterfoo); trailing slashes are normalized. Unset (the default) leaves behaviour byte-identical to today — all existing tests pass unchanged; regression tests and docs added.

We hit this in production at EOPF-Explorer/platform-deploy#343 and currently run this guard as a patched image.

Author attestation

  • I am a human, these are my changes, and I have reviewed and understood every change and can explain why each is correct.

AI-assisted: implementation and tests drafted with Claude, reviewed by me, and validated against the full test suite (478 passed) and pre-commit hooks (ruff, isort, mypy).

… root_path rewriting

On shared-host deployments (e.g. eoapi-k8s defaults: proxy at /stac,
titiler at /raster, /vector, /browser on one hostname), STAC responses
carry same-host links to sibling services. ProcessLinksMiddleware cannot
distinguish these from its own links by netloc — with OVERRIDE_HOST=false
the upstream generates its links with the request netloc too — so it
prepends ROOT_PATH to them, producing broken links (/stac/raster/... 404).

Add an opt-in ROOT_PATH_SKIP_PREFIXES setting: same-host links whose path
matches a configured prefix (path-segment-aware) are left untouched.
Unset (default) keeps behavior unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions github-actions Bot added the fix label Jul 22, 2026
@lhoupert
lhoupert marked this pull request as draft July 22, 2026 15:10
… prefix

- add a regression test asserting upstream-host links are still rewritten
  even when their path matches a skip prefix (the setting describes sibling
  services on the proxy's public hostname)
- raise on a bare '/' prefix instead of silently dropping it (it would
  otherwise read as 'skip everything' but do nothing)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@pantierra

Copy link
Copy Markdown
Contributor

I looked into this issue and overall the approach is fine. I put my suggestions directly into code with f383dbd

This PR is made of @lhoupert repository. If my suggestions are helpful, i suggest we base this PR on this repos fix/scope-root-path-link-rewrite-local branch.

@lhoupert lhoupert closed this Jul 23, 2026
@lhoupert

Copy link
Copy Markdown
Contributor Author

close for duplicate #198

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ProcessLinksMiddleware prepends ROOT_PATH to same-host links it does not serve (e.g. titiler on a shared host)

2 participants