0.11.0 — deep-audit hardening
Minor release. Additive only — no breaking changes.
This release ships the full remediation of the 2026-06-14 full-codebase deep
audit: 35 confirmed findings closed across security, correctness, public API,
test quality, and documentation.
New public names
from httpware import ResponseTooLargeErrorAsyncClient / Client gain an opt-in max_error_body_bytes: int | None = None.
Security hardening
- URL secret redaction. Request URLs that reach logs, OpenTelemetry span
events, andStatusErrormessages/reprare now sanitized:user:pass@
userinfo is stripped and the values of known-sensitive query/fragment
parameters (api_key,access_token,token,secret,password, …) are
masked withREDACTED. Redaction is centralized at the_emit_event
emission boundary, so every resilience event is covered and a future event
cannot reintroduce the leak. Non-secret URLs are byte-identical to before. - Bounded error bodies. With
max_error_body_bytesset,stream()raises
the newResponseTooLargeErroron a 4xx/5xx whose declaredContent-Length
exceeds the cap, before reading the body. Default (None) is unchanged.
A chunked error body with no declared length is still read — a hard mid-read
cap would require httpx2 private API; that deeper bound is tracked as
deferred work. - Documented trust boundaries.
trust_env=Trueproxy inheritance and the
fact thatexc.response.requestexposesAuthorization/Cookieheaders are
now called out inarchitecture/.
Correctness fixes
- RetryBudget no longer spends a token on a
Retry-Aftergive-up. When a
server'sRetry-Afterexceedsmax_delay, the give-up check now runs before
budget.try_withdraw(), so aRetry-Afterflood can't drain shared-budget
capacity for unrelated requests (sync and async). - Hostile headers no longer crash the retry loop. A
Retry-Afterof a few
hundred digits raisedOverflowError;_parse_retry_afternow degrades it
to "no hint".full_jitter_delaylikewise no longer raises at very large
attempt indices — it clamps tomax_delayas documented. - Decoder/extras robustness. The pydantic import is fully guarded so the
decoder module loads without the extra (the friendlyImportErroris the
real fail-fast path), andmsgspec's internal type walk raises a friendly
ImportErrorrather thanNameErrorwhen the extra is absent. AsyncClientstreaming-body detection now recognizes non-replayable sync
iterables explicitly instead of relying on an undocumented httpx2 detail.- URL sanitizer no longer emits a malformed
http:///pathfor the
credentials-but-no-host edge case.
Public API
httpware.middlewarenow defines__all__, sofrom httpware.middleware import *no longer leakshttpx2, typing helpers, or submodules.
Quality
- Test suite hardened: closed coverage gaps (sync terminal mapping, the
CookieConflictbranch,TimeoutErrortripping the circuit breaker, the
three never-constructed status errors), added sync/async parity mirrors and
Clientoverload typing tests, replaced a flakytime.sleep-based bulkhead
test with a deterministic barrier, and pinned a budget-test clock. - Documentation accuracy fixes across
architecture/and the docs site.
Shipped via
PRs #62 (pydantic isolation), #63 (security cluster), #64 (correctness +
public API), #65 (test quality), #66 (docs). See
planning/audits/2026-06-14-deep-audit.md
for the full audit.