Skip to content

fix: resolve relative links against the URL after an HTTP redirect - #1825

Open
devtejasx wants to merge 2 commits into
stac-utils:mainfrom
devtejasx:fix/redirect-base-href-1816
Open

devtejasx wants to merge 2 commits into
stac-utils:mainfrom
devtejasx:fix/redirect-base-href-1816

Conversation

@devtejasx

Copy link
Copy Markdown
Contributor

Related Issue(s):

Description:

When a STAC object is read over HTTP and the server redirects, the requested URL became the object's self href, so relative links resolved against the old location. Per RFC 3986 section 5.1.3, the base is the URL the document was actually retrieved from.

  • DefaultStacIO (urllib and urllib3 paths) and RetryStacIO record the final URL of each read via a small _set_final_href / _get_final_href pair on StacIO. The entry is cleared when a later read of the same href isn't redirected, so a stale redirect isn't reused.
  • StacIO.read_stac_object and STACObject.from_file use the final URL as the self href.
  • urllib3 reports the raw Location header (often relative), so it's resolved against the URL of the request that was redirected, taken from the retry history.

Custom StacIO subclasses that don't call _set_final_href keep the current behaviour.

Tests: a local HTTP server that 308-redirects /old/ to /new/, parametrized over urllib, urllib3 and RetryStacIO, and over Catalog.from_file and pystac.read_file. The new tests fail on main and pass here.

PR Checklist:

  • Pre-commit hooks pass (run pre-commit run --all-files). I ran ruff check, ruff format --check and mypy on the changed files rather than the hooks; mypy reports no new errors.
  • Tests pass (run pytest). tests/test_stac_io.py 26 passed. The full suite is 1051 passed, 5 skipped, with 20 shutil.Error errors in asset/item copy tests that fail the same way on main on Windows.
  • Documentation has been updated to reflect changes, if applicable
  • This PR maintains or improves overall codebase code coverage
  • This PR's title is formatted per conventional commits

AI tool usage:

  • AI tools supported the development of this PR, per the stac-utils AI tool policy. I used Claude Code to reproduce the issue, write the change and tests, and run the checks above.

When a STAC object was read over HTTP and the server redirected, the
requested URL became the object's self href, so relative links resolved
against the old location. RFC 3986 section 5.1.3 says the base URI is the
one the document was actually retrieved from.

DefaultStacIO and RetryStacIO now record the final URL of each read, and
read_stac_object and STACObject.from_file use it as the self href.
urllib3 reports the raw Location header, so it is resolved against the
request that was redirected.

Closes stac-utils#1816
urllib only follows 308 redirects from Python 3.11 on, so the
urllib-backed cases failed on 3.10 before reaching the code under test.
@gadomski
gadomski self-requested a review October 5, 2026 13:57

This branch has not been deployed

No deployments
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.

1 participant