Breaking Changes
- Eventlet worker removed: The
eventletworker class has been dropped. Migrate togevent,gthread, ortornado.
New Features
- ASGI Framework Compatibility Suite: New end-to-end compatibility test harness covering Starlette, FastAPI, Litestar, Quart, Sanic, and BlackSheep. Current grid passes 438/444 tests (98%).
- ASGI Test Suite Expansion: 134 additional ASGI unit tests covering protocol semantics, lifespan, websockets, and chunked framing.
Security
- HTTP/1.1 Request-Target Validation (RFC 9112 sections 3.2.3, 3.2.4):
- Reject
authority-formrequest-target outsideCONNECT - Reject
asterisk-formrequest-target outsideOPTIONS - Reject
relative-referencerequest-targets
- Reject
- Header Field Hardening (RFC 9110):
- Reject control characters in header field-value (section 5.5)
- Reject forbidden trailer field-names (section 6.5.1)
- Reject
Content-Lengthlist form (RFC 9112 section 6.3)
- Request Smuggling Hardening:
- Tighten keepalive gate and scope
finish_bodybyte cap - Keep
_body_receiveralive across the keepalive smuggling gate so pipelined requests cannot re-enter a closed body - Address parser/protocol findings from a six-point WSGI/ASGI audit
- Tighten keepalive gate and scope
- PROXY Protocol (ASGI): Enforce
proxy_allow_ipsand tighten v1/v2 parsing in the ASGI callback parser. - Connection Draining: Drain the connection on close per RFC 9112 section 9.6 to prevent reset-on-close truncation.
Bug Fixes
- Body Framing on HEAD/204/304:
- Keep
Content-Lengthon HEAD and 304 responses (#3621) - Drop body framing on HEAD/204/304 even when the framework set it
- Warn once when an ASGI app emits a body for a no-body response
- Keep
- HTTP/2 ASGI:
- Fix
_handle_stream_endedto set_body_completein the async HTTP/2 handler so request bodies finalize correctly on stream end - Add
InvalidChunkExtensionmapping and fast-parser support in ASGI tests (#3565)
- Fix
- HTTP/1.1 100-Continue: Stop adding
Transfer-Encoding: chunkedto 100-Continue interim responses. - WebSocket Close Handshake (RFC 6455):
- Comply with the close handshake state machine
- Close the transport after the close handshake completes
- Fix binary send when the
textkey isNone
- Early Hints: Validate headers in the
early_hintscallback to matchprocess_headers; pass only the header name toInvalidHeader(#3588). - ASGI Framework Fixes:
- Fix ASGI disconnect handling for Django-style apps
- Fix Litestar request handling (use raw ASGI receive for body/headers)
- Fix Litestar HTTP endpoints for compatibility tests
- Fix Quart headers endpoint to normalize keys to lowercase
- Fix Quart WebSocket close test app (missing
accept()) - Fix duplicate
Transfer-Encodingheader for BlackSheep streaming
Refactoring
- Split
BodyReceiver._closedinto separate transport and body-wait flags for clearer keepalive/EOF semantics.
Changes
- Fast HTTP Parser: Require
gunicorn_h1c >= 0.6.5. Drop the lastpython_onlytest markers; the C extension is now used wherever available (CPython only; PyPy continues to use the Python parser). - Test Dependencies: Add
h2anduvloopto thetestingextra; removeeventlet. - Docker Build: Bump GitHub Actions
docker/setup-qemu-action,docker/setup-buildx-action,docker/login-action,docker/build-push-action, anddocker/metadata-actionto current major versions.
Full changelog: 25.3.0...26.0.0