key helper on the challenged host; retry POSTs too

main

Commit

Soph3mo ago

Two correctness gaps caught in review:

  1. After a 3xx on /info/refs, the host that actually returns 401 is in res.Request.URL, which can differ from c.EndpointURL. Querying the helper with c.EndpointURL fetched (and on success approved) credentials under the wrong key — a miss on the next run, or a poisoned key if the retry happened to work via a follow-up redirect. New challengeURLFor() preserves the original repo path but swaps in the post-redirect scheme/host before consulting the helper.

  2. Helper fallback existed only on GET /info/refs. Servers that allow anonymous discovery but require auth on the actual pack POST (e.g. Gerrit anonymous-readable + authenticated push) would fail hard. PostRPCStreamBody now does the same lookup → retry → approve/reject dance, gated on the body being io.Seeker so we can rewind it for the second attempt. PostRPC / PostRPCStream always pass bytes.NewReader, which is seekable; a caller that hands in a raw non-seekable Reader sees the 401 surface as-is (documented in the doc comment).

The retry lifecycle is now in tryHelperRetry, shared between GET and POST. Four new tests cover redirect-host keying and the POST 401-retry permutations.

Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com Entire-Checkpoint: 991254d4f73a

Checkpoints

can you take a look at https://github.com/entireio/git-sync/issues/63

Claude CodeOpus 4.7[1m]
View session
Checkpoint 1