Skip to content

Keep an out-of-scope redirect from stopping the crawl - #86

Merged
tamnd merged 1 commit into
mainfrom
fix/redirect-scope-fallback
Aug 10, 2026
Merged

Keep an out-of-scope redirect from stopping the crawl#86
tamnd merged 1 commit into
mainfrom
fix/redirect-scope-fallback

Conversation

@tamnd

@tamnd tamnd commented Aug 10, 2026

Copy link
Copy Markdown
Owner

Follow-up to #74.

urlx.SameSite matches hostnames exactly (urlx/urlx.go:212), with subdomains in scope only under --subdomains. So when a seed https://example.com/ redirects to https://www.example.com/, which is how a large share of the web is configured, resolving the page's relative links against the final URL puts every one of them out of scope. They stay absolute, none are enqueued, and the crawl saves the seed page and stops. The reverse, www to apex, breaks the same way.

The failure is quiet. Assets are matched with SameRegistrableDomain, which folds www.example.com and example.com together, so they keep downloading and the run ends with a complete-looking single page and no error.

Probe against the merged tree before this change:

resolve base = https://www.example.com/
link resolves to https://www.example.com/about ; InScope=false

scopedResolveBase falls back to the document <base href>, and then to the enqueued URL, when the redirect target is out of scope. A redirect that genuinely leaves the site (example.com/go/x to partner.com) keeps the previous behaviour, since those links are out of scope either way and get re-fetched and re-redirected if they are reached on their own.

TestScopedResolveBaseKeepsRedirectInScope covers apex to www, www to apex, a same-host redirect still winning, an off-scope document base being dropped, and an in-scope document base surviving an off-scope redirect. Each case also asserts the chosen base is in scope, which is the property that actually matters.

Separately worth an issue rather than this PR: when the seed itself redirects to another host, adopting the final host as the crawl scope is probably what kage clone example.com means. That changes c.seedHost and the output directory, so it is a design decision.

urlx.SameSite matches hostnames exactly, so a seed that redirects apex to
www (or the reverse) lands on a host the scope rejects. Resolving the
page's relative links against that host put every one of them out of
scope: they stayed absolute, nothing was enqueued, and the crawl saved
the seed page and stopped. Assets go through SameRegistrableDomain and
kept downloading, so the run ended with a complete-looking single page
and no error.

scopedResolveBase falls back to the document <base href>, and then to the
enqueued URL, when the redirect target is out of scope. A redirect that
genuinely leaves the site keeps the previous behaviour, since those links
are out of scope either way and are re-fetched and re-redirected if they
are reached on their own.

Follow-up to #74.
@tamnd
tamnd merged commit 0323633 into main Aug 10, 2026
9 checks passed
@tamnd
tamnd deleted the fix/redirect-scope-fallback branch August 10, 2026 07:01
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