Bug Fixes
==========
- HTTP/2 ASGI Body Duplication: Fix request body being received twice in HTTP/2
ASGI requests, causing JSON parsing errors with "Extra data" messages (#3558)
- ASGI Chunked EOF Handling: Add finish() method to callback parser to handle
chunked encoding edge case where connection closes before final CRLF after
zero-chunk
- HTTP/2 Documentation: Fix http_protocols examples to use comma-separated
string instead of list syntax (#3561)
- Chunked Encoding: Reject chunk extensions containing bare CR bytes per RFC
9112 (#3556)
- Request Line Limit: Fix --limit-request-line 0 to mean unlimited as
documented, instead of using default maximum. Works with both Python and fast
C parser. (#3563)
- uWSGI Async Workers: Fix InvalidUWSGIHeader: incomplete header error when
using gevent or gthread workers with uwsgi protocol behind nginx.
- FileWrapper Iterator Protocol: Add __iter__ and __next__ methods to
FileWrapper for full PEP 3333 compliance. Previously only supported old-style
__getitem__ iteration which broke code explicitly using iter() or next().
Security =============
- ASGI Parser Header Validation: Add security checks per RFC 9110/9112:
- Reject duplicate Content-Length headers
- Reject requests with both Content-Length and Transfer-Encoding
- Reject chunked transfer encoding in HTTP/1.0
- Reject stacked chunked encoding
- Validate Transfer-Encoding values
- Strict chunk size validation
Changes ==========
- Fast HTTP Parser: Update to gunicorn_h1c >= 0.6.3 for asgi_headers property
and InvalidChunkExtension validation for bare CR rejection
- ASGI PROXY Protocol: Add PROXY protocol v1/v2 support to callback parser
- Docker Images: Update to Python 3.14
New Features ============
- Fast HTTP Parser (gunicorn_h1c 0.6.0): Integrate new exception types and
limit parameters from gunicorn_h1c 0.6.0 for both WSGI and ASGI workers
- Requires gunicorn_h1c >= 0.6.0 for http_parser='fast'
- Falls back to Python parser in auto mode if version not met
- Proper HTTP status codes for limit errors (414, 431)
Performance ============
- ASGI HTTP Parser Optimizations: Improve ASGI worker HTTP parsing performance
- Callback-based parsing with direct bytearray buffer operations
- Use bytearray.find() directly instead of converting to bytes first
- Use index-based iteration for header parsing instead of list.pop(0) (O(1) vs
O(n))
Signed-off-by: Wang Mingyu <wangmy@fujitsu.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
Upgrade to release 25.1.0:
- Control Interface (gunicornc): Add interactive control interface
for managing running Gunicorn instances, similar to birdc for
BIRD routing daemon
- Unix socket-based communication with JSON protocol
- Interactive mode with readline support and command history
- Commands: show all/workers/dirty/config/stats/listeners
- Worker management: worker add/remove/kill, dirty add/remove
- Server control: reload, reopen, shutdown
- New settings: --control-socket, --control-socket-mode,
--no-control-socket
- New CLI tool: gunicornc for connecting to control socket
- Dirty Stash: Add global shared state between workers via dirty.stash
- In-memory key-value store accessible by all workers
- Supports get, set, delete, clear, keys, and has operations
- Useful for sharing state like feature flags, rate limits, or
cached data
- Dirty Binary Protocol: Implement efficient binary protocol for
dirty arbiter IPC using TLV (Type-Length-Value) encoding
- More efficient than JSON for binary data
- Supports all Python types: str, bytes, int, float, bool, None,
list, dict
- Better performance for large payloads
- Dirty TTIN/TTOU Signals: Add dynamic worker scaling for dirty
arbiters
- Send SIGTTIN to increase dirty workers
- Send SIGTTOU to decrease dirty workers
- Respects minimum worker constraints from app configurations
- ASGI Worker: Promoted from beta to stable
- Dirty Arbiters: Now marked as beta feature
License-Update: Update years
Signed-off-by: Leon Anavi <leon.anavi@konsulko.com>
Signed-off-by: Khem Raj <raj.khem@gmail.com>