Skip to content

HTTP-01: Do our own redirect handling - #8961

Open
aarongable wants to merge 3 commits into
mainfrom
simplify-http-loop
Open

HTTP-01: Do our own redirect handling#8961
aarongable wants to merge 3 commits into
mainfrom
simplify-http-loop

Conversation

@aarongable

@aarongable aarongable commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Note

This PR builds on #8905, only the most recent commit is new. This PR also addresses all of my review comments left on that PR; I'd be happy landing that PR as-is as long as this PR follows it.

This PR makes two large simplifications to the VA's HTTP-01 validation code, and a number of smaller modifications as knock-on effects.

The first large simplification is the replacement of Go's default redirect handling with a straightforward loop that we manage directly. Although hooking into Go's http.Client.CheckRedirect function was useful, it required our code to be non-linear because that function is called as a callback. We'd set up a redirect request for Go to make, it would magically happen in the background, and then our straight-line code would deal with the result, including potentially falling back from an IPv6 attempt to an IPv4 attempt outside Go's redirect handling. This has resulted in numerous bugs over time.

The new code instead tells Go to never follow redirects on its own, and just return the redirect response to us. We then handle every validation response with a few simple cases:

  • if it was an error we're willing to retry, fall back to IPv4;
  • if it was some other form of error, error out;
  • if it was a redirect, enforce our redirect policy and then follow it; or
  • if it was some other form of success, return the result to the validation checker.

This does introduce some additional complexity (e.g. having to track the referer ourselves, and not attach it when redirecting from https to http), but I think the tradeoff is worth it.

The second large simplification is in how we keep track of what requests we're making. Historically we've had both an httpValidationTarget and a core.ValidationRecord which stored redundant information and were used almost interchangeably. This change gets rid of httpValidationTarget. Prior to each iteration of the loop described above, we construct a ValidationRecord. Each loop appends that record to the list prior to making the validation request, so that any errors encountered in the process will be associated with the most recent entry in the list of records. And the functions which actually make the request extract their parameters (the IP address, the port, the path, etc) directly from the ValidationRecord, ensuring that we're recording exactly what we do, with no drift.

Smaller knock-on changes include:

  • reducing the total number of requests we're willing to make from 12 (as it currently stands: 1 initial request, 10 redirects, and 1 fallback) or 22 (as Shiloh's PR makes it: 1 initial request, 10 redirects, and one fallback per other request), to 10 (as most readers probably thought we were doing in the past);
  • combining extractRequestTarget and processRedirect (the old closure) into a single newValidationRecordFromRedirect function;
  • changing the preresolvedDialer to store the port as an int, so we don't have to convert it back and forth between the validation record and the dialer;
  • upgrading our body reading to use the new core.ErrOnLimitReader; and
  • of course many updates to the tests.

An LLM was used to review and improve an earlier version of this PR, and to do most of the unit test case updates.

sheurich and others added 3 commits August 4, 2026 11:35
Retry the request and validation target selected by redirect handling so IPv6 dial failures can fall back to IPv4 at each hop. Resume from the request whose dial failed to avoid replaying earlier redirects.

Add regression coverage for the reported HTTP-to-HTTPS two-fallback sequence.
@aarongable
aarongable marked this pull request as ready for review August 20, 2026 20:35
@aarongable
aarongable requested a review from a team as a code owner August 20, 2026 20:35
@aarongable
aarongable requested a review from ezekiel August 20, 2026 20:35
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.

2 participants