Post to Bar over http.client to keep Access header names intact - #63
Merged
Conversation
urllib.request title-cases header names in AbstractHTTPHandler.do_open, so CF-Access-Client-Id went out as Cf-Access-Client-Id and Cloudflare Access answered 403. http.client's putheader writes names verbatim. The transport pins the HTTPS origin before connecting, never follows a redirect, reads a bounded response, and closes the connection in a finally block. Retries reuse the same body and Idempotency-Key, and Retry-After is matched case-insensitively and capped. Also names the collector in a User-Agent, since http.client sends none and an unnamed agent invites edge bot rules to answer instead of Bar, and treats ssl.SSLCertVerificationError as a permanent trust failure rather than retrying it as a transient network error. Allowlists the transport tests in the release-hygiene network check. They bind only loopback servers to assert wire-level header spelling, and tests/ is not in the wheel.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces the Bar POST transport so Cloudflare Access sees the header
names it requires.
Root cause
urllib.requesttitle-cases header names inAbstractHTTPHandler.do_open, soCF-Access-Client-Idreached the edgeas
Cf-Access-Client-Idand Access answered 403. Captured on the wire:http.client.putheaderwrites names verbatim, so the spelling survives.The request Bar now receives
Transport properties
and is independently re-parsed to require HTTPS, the exact hostname,
port 443, and no userinfo or fragment. A non-HTTPS endpoint is
rejected before the connection factory is called.
HTTPSConnectioncontext verifiescertificates and hostnames with a TLS 1.2 floor.
http.clientdoes not follow them, so a 3xx raisesimmediately. A test stands up a second server as a credential sink and
asserts it receives nothing.
checked before the status is interpreted.
close()runs in afinally. After threefailed attempts, no sockets remain open.
every attempt sends identical bytes under the same
Idempotency-Key.fails on the first attempt, so a 403 no longer burns three requests.
Retry-Afteris matched case-insensitively and capped at 60 seconds.Also in this change
User-Agent.http.clientsends none, and an unnamed agent is aplausible trigger for edge bot rules. The collector now names itself
here exactly as it already does to GitHub.
ssl.SSLCertVerificationErrorsubclasses
OSError, so it was being retried three times and reportedas a generic network error, which would bury an intercepted
certificate. It now fails immediately with a distinct message. A
companion test proves ordinary socket errors still retry.
loopback servers to assert wire-level header spelling, and
tests/isnot in the wheel, which packages only
link_mcpandlink_core.Verification
Collector tests 37 passed, full suite 1047 passed, release hygiene
passed, hygiene tests 11 passed, ruff clean, actionlint clean.
Header spelling, cleanup, idempotent retry bodies, and
Retry-Aftercasing were each confirmed against real loopback socket servers reading
raw request bytes, not mocks.