GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — fix: keep multi-step auth responses under the response body cap by lesnik512 · Pull Request #153 · modern-python/httpware

Conversation

@lesnik512

@lesnik512 lesnik512 commented Oct 3, 2026

Copy link
Copy Markdown
Member

httpx2's _send_handling_auth reads every intermediate auth-flow response with an unbounded response.read(). Any auth= that takes more than one step therefore bypassed max_response_body_bytes, with or without redirects: the 401 challenge of httpx2.DigestAuth, and custom flows such as a token refresh that retries after calling a token endpoint. auth= has been forwarded since 0.18, so a server could make a capped client buffer an arbitrarily large challenge body.

How

With a cap set, httpware now drives the auth flow itself (auth.async_auth_flow / sync_auth_flow, public API), wrapped around the redirect loop from #152, the same nesting httpx2 uses.

  • Every wire request goes out with a no-op httpx2.Auth(), so httpx2 never applies auth on its own. Which auth runs is decided like httpx2 does: client.auth, else Basic from URL credentials, else none (_request_auth, a public-API copy of the private _build_request_auth).
  • Intermediate auth responses are closed unread and kept in history. An auth with requires_response_body = True gets each response buffered under the cap instead, so an oversized token response raises ResponseTooLargeError.
  • Behaviour otherwise matches the no-cap path, checked against native httpx2: auth steps count toward max_redirects (checked before every send), nested .history of each hop, history order across auth steps, and the error raised for a malformed Digest challenge.
  • Without a cap nothing changes.

Side effects

  • DigestAuth now answers a challenge that arrives after a redirect under a cap. In 0.20.0 it could not (noted in that release).
  • Credentials embedded in a redirect Location are no longer applied on the capped path, matching httpx2 (0.20.0 sent hops with auth=None, which applied them).
  • stream() with a requires_response_body auth yields a body already read under the cap. httpx2 reads that body anyway; docs/errors.md now says so.
  • _read_capped_and_close[_async] is shared by _terminal and the auth loop.

Tests

tests/test_client_body_cap_auth.py, sync and async mirrored: Digest challenge body read only without a cap (verbs and stream()), token refresh under and over the cap (verbs and stream()), URL credentials with and without a cap, Digest after a redirect with identical nested history with and without a cap, auth steps counting toward max_redirects, and a malformed challenge raising the same TransportError. The Digest and stream tests fail against main.

Verification

just lint-ci, just test-ci (1001 passed, 100% coverage), just docs-build, just adr-check.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
lesnik512 added 2 commits October 3, 2026 12:42
@lesnik512
fix: keep multi-step auth responses under the response body cap
fda521f
httpx2 reads every intermediate auth-flow response (a DigestAuth
challenge, a token-refresh call) without a limit. With a cap set,
httpware now drives the auth flow itself around its redirect loop.
@lesnik512
fix: match httpx2 max_redirects counting and history across auth steps
9a174dd
Also cover stream() with auth flows and share the capped read-and-close
step between the terminal and the auth loop.
@lesnik512
lesnik512 merged commit afeaf59 into main Oct 3, 2026
13 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@lesnik512
lesnik512 deleted the fix/cap-auth-flow-bodies branch October 3, 2026 09:50
@lesnik512 lesnik512 mentioned this pull request Oct 3, 2026
Let callers bound or skip the intermediate bodies read while following redirects and auth flows pydantic/httpx2#1249
Open
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@lesnik512
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.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.