Skip to content

Only follow robots.txt redirects on the same host - #2077

Open
rzo1 wants to merge 1 commit into
mainfrom
fix/robots-redirect-same-host
Open

Only follow robots.txt redirects on the same host#2077
rzo1 wants to merge 1 commit into
mainfrom
fix/robots-redirect-same-host

Conversation

@rzo1

@rzo1 rzo1 commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

HttpRobotRulesParser resolved the Location header of a robots.txt redirect and re-fetched it without checking scheme, host or port, so the fetch could end up on any host the redirect named.

A redirect which only replaces http with https on the same host and port is still followed, whatever this is configured to, so the usual http://…/robots.txt -> https://…/robots.txt is unaffected. Anything else is now followed only when the target is http or https and shares scheme, host and port with the URL it was reached from; http.robots.redirect.crossorigin.allow (default false) restores the old behaviour for http and https targets.

getCacheKey derives the default port from the scheme, so an upgraded target has a different key although no other host is involved, and refusing it would leave that very common redirect with no rules at all. Only that direction is exempt — https to http would put the configured request headers on the wire in clear and let rules read over plain text replace the ones the redirect was reached from.

A redirect which is not followed no longer ends as allow-all in the success cache. It yields no rules for the host, cached in the error cache like a 429 or a 5xx, so nothing is crawled there until the redirect is resolved; http.robots.redirect.refused.allow: true restores allow-all. The refusal is logged at warn level with the target, the reason and the setting that changes it.

Following a redirect to another origin re-fetches robots.txt with the headers configured through http.basicauth.* and http.custom.headers, as any other request does. That is now stated where the setting is defined and logged once at configuration time when either is set. http.filter.ipaddress.exclude gained a linklocal rule to restrict which addresses those fetches may reach — link-local is matched by neither loopback nor sitelocal, so the documented "localhost,sitelocal" example did not cover it.

Sites serving robots.txt through a redirect to another host, a CDN for instance, are affected. Documented in crawler-default.yaml and configuration.adoc.

For all changes

  • Is there a issue associated with this PR? Is it referenced in the commit message? - no issue

  • Does your PR title start with #XXXX where XXXX is the issue number you are trying to resolve? - no issue

  • Has your PR been rebased against the latest commit within the target branch (typically main)?

  • Is your initial contribution a single, squashed commit?

  • Is the code properly formatted with mvn git-code-format:format-code -Dgcf.globPattern="**/*" -Dskip.format.code=false?

For code changes

  • Have you ensured that the full suite of tests is executed via mvn clean verify? - core module tests only
  • Have you written or updated unit tests to verify your changes? - new HttpRobotRulesParserRedirectTargetTest; the existing redirect test sets the new key, since its chain crosses ports
  • If adding new dependencies to the code, are these dependencies licensed in a way that is compatible for inclusion under ASF 2.0? - no new dependencies
  • If applicable, have you updated the LICENSE file, including the main LICENSE file? - n/a
  • If applicable, have you updated the NOTICE file, including the main NOTICE file? - n/a

@rzo1 rzo1 added this to the 4.0.0 milestone Aug 27, 2026
@rzo1
rzo1 force-pushed the fix/robots-redirect-same-host branch from 3226dea to 1685474 Compare August 27, 2026 12:53

@dpol1 dpol1 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not convinced by the default. As it stands http://h/robots.txt -> https://h/robots.txt (same host, only the scheme changes) gets refused, and from there we crawl the site with no rules at all. Tried it on a scratch test. Threads.

Comment thread core/src/main/java/org/apache/stormcrawler/protocol/HttpRobotRulesParser.java Outdated
@rzo1 rzo1 assigned rzo1 and unassigned jnioche and dpol1 Aug 28, 2026
@rzo1
rzo1 requested a review from jnioche August 28, 2026 07:28
@rzo1
rzo1 marked this pull request as draft August 28, 2026 08:39
HttpRobotRulesParser followed the Location header of a robots.txt response
for up to 5 hops, honouring an absolute target verbatim and re-fetching it
with no restriction, so the crawled site chose which host was requested.
A redirect is now only followed when the target shares scheme, host and
port with the URL it was reached from, unless
http.robots.redirect.crossorigin.allow is set.

A redirect which only replaces http with https while staying on the same
host and port is always followed. getCacheKey derives the default port
from the scheme, so such a target has a different key although no other
host is involved, and refusing it left the very common apex redirect
without any rules. Only that direction is exempt: https to http would send
the headers configured for the fetch unencrypted and would let rules read
over a plain text connection replace the ones the redirect was reached
from.

A redirect which is not followed no longer ends as allow-all in the
success cache. It yields no rules for the host, cached in the error cache
like a 429 or a 5xx, so nothing is crawled there until the redirect is
resolved. http.robots.redirect.refused.allow: true restores the previous
behaviour and crawls the host without any rules. The refusal is logged at
warn level, naming the target, why it was not followed and which setting
changes it.

Following a redirect to another origin re-fetches the robots.txt with the
headers configured through http.basicauth.* and http.custom.headers, as
any other request does. That is now stated where the setting is defined
and logged once at configuration time when either is set, and
http.filter.ipaddress.exclude gained a linklocal rule so that the
addresses those fetches may reach can be restricted: link local addresses
are matched by neither loopback nor sitelocal, so the documented example
did not cover them.
@rzo1
rzo1 marked this pull request as ready for review August 28, 2026 09:33
@rzo1
rzo1 force-pushed the fix/robots-redirect-same-host branch from 1685474 to dbf0bd1 Compare August 28, 2026 09:34
@rzo1
rzo1 requested a review from dpol1 August 28, 2026 09:41

@dpol1 dpol1 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. The one-way scheme-upgrade exemption and the refused redirect going to the error cache instead of allow-all cover both points, and refused.allow keeps the old behaviour one line away for whoever needs it. Only the description: it still opens with "shares scheme, host and port", the http -> https exemption deserves the first sentence since that's what most people will hit.

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.

3 participants