mirror of
https://github.com/frappe/gunicorn.git
synced 2026-07-07 13:11:30 +08:00
Update to gunicorn_h1c >= 0.6.2 for asgi_headers support
- Use asgi_headers property (lowercase names) from fast parser - Bump version to 25.3.0 - Update changelog with all changes for this release
This commit is contained in:
parent
cbd27e82a2
commit
d43acb8fe0
@ -1,6 +1,36 @@
|
|||||||
<span id="news-2026"></span>
|
<span id="news-2026"></span>
|
||||||
# Changelog - 2026
|
# Changelog - 2026
|
||||||
|
|
||||||
|
## 25.3.0 - 2026-03-26
|
||||||
|
|
||||||
|
### 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](https://github.com/benoitc/gunicorn/issues/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
|
||||||
|
|
||||||
|
### 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.2 for `asgi_headers` property
|
||||||
|
which provides headers with lowercase names directly from the C parser
|
||||||
|
|
||||||
|
- **ASGI PROXY Protocol**: Add PROXY protocol v1/v2 support to callback parser
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 25.2.0 - 2026-03-24
|
## 25.2.0 - 2026-03-24
|
||||||
|
|
||||||
### New Features
|
### New Features
|
||||||
|
|||||||
@ -1,6 +1,36 @@
|
|||||||
<span id="news"></span>
|
<span id="news"></span>
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 25.3.0 - 2026-03-26
|
||||||
|
|
||||||
|
### 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](https://github.com/benoitc/gunicorn/issues/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
|
||||||
|
|
||||||
|
### 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.2 for `asgi_headers` property
|
||||||
|
which provides headers with lowercase names directly from the C parser
|
||||||
|
|
||||||
|
- **ASGI PROXY Protocol**: Add PROXY protocol v1/v2 support to callback parser
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 25.2.0 - 2026-03-24
|
## 25.2.0 - 2026-03-24
|
||||||
|
|
||||||
### New Features
|
### New Features
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
# This file is part of gunicorn released under the MIT license.
|
# This file is part of gunicorn released under the MIT license.
|
||||||
# See the NOTICE for more information.
|
# See the NOTICE for more information.
|
||||||
|
|
||||||
version_info = (25, 2, 0)
|
version_info = (25, 3, 0)
|
||||||
__version__ = ".".join([str(v) for v in version_info])
|
__version__ = ".".join([str(v) for v in version_info])
|
||||||
SERVER = "gunicorn"
|
SERVER = "gunicorn"
|
||||||
SERVER_SOFTWARE = "%s/%s" % (SERVER, __version__)
|
SERVER_SOFTWARE = "%s/%s" % (SERVER, __version__)
|
||||||
|
|||||||
@ -835,7 +835,9 @@ class CallbackRequest:
|
|||||||
req.version = parser.http_version
|
req.version = parser.http_version
|
||||||
|
|
||||||
# Headers - store both bytes (for ASGI scope) and strings (for compatibility)
|
# Headers - store both bytes (for ASGI scope) and strings (for compatibility)
|
||||||
req.headers_bytes = list(parser.headers)
|
# Use asgi_headers (lowercase names) if available (fast parser >= 0.6.2),
|
||||||
|
# otherwise fall back to headers (Python parser already uses lowercase)
|
||||||
|
req.headers_bytes = list(getattr(parser, 'asgi_headers', None) or parser.headers)
|
||||||
req.headers = [
|
req.headers = [
|
||||||
(n.decode('latin-1').upper(), v.decode('latin-1'))
|
(n.decode('latin-1').upper(), v.decode('latin-1'))
|
||||||
for n, v in parser.headers
|
for n, v in parser.headers
|
||||||
|
|||||||
@ -53,7 +53,11 @@ tornado = ["tornado>=6.5.0"]
|
|||||||
gthread = []
|
gthread = []
|
||||||
setproctitle = ["setproctitle"]
|
setproctitle = ["setproctitle"]
|
||||||
http2 = ["h2>=4.1.0"]
|
http2 = ["h2>=4.1.0"]
|
||||||
fast = ["gunicorn_h1c>=0.6.0"]
|
|
||||||
|
|
||||||
|
|
||||||
|
fast = ["gunicorn_h1c>=0.6.2"]
|
||||||
|
|
||||||
testing = [
|
testing = [
|
||||||
"gevent>=24.10.1",
|
"gevent>=24.10.1",
|
||||||
"eventlet>=0.40.3",
|
"eventlet>=0.40.3",
|
||||||
|
|||||||
@ -3,4 +3,4 @@ coverage
|
|||||||
pytest>=7.2.0
|
pytest>=7.2.0
|
||||||
pytest-cov
|
pytest-cov
|
||||||
pytest-asyncio
|
pytest-asyncio
|
||||||
gunicorn_h1c>=0.6.0
|
gunicorn_h1c>=0.6.2
|
||||||
|
|||||||
@ -21,7 +21,7 @@ def http_parser(request):
|
|||||||
"""Parametrize tests over http_parser implementations."""
|
"""Parametrize tests over http_parser implementations."""
|
||||||
if request.param == "fast":
|
if request.param == "fast":
|
||||||
gunicorn_h1c = pytest.importorskip("gunicorn_h1c", reason="gunicorn_h1c required")
|
gunicorn_h1c = pytest.importorskip("gunicorn_h1c", reason="gunicorn_h1c required")
|
||||||
# Require >= 0.6.0 for header framing validation
|
# Require >= 0.6.2 for asgi_headers support
|
||||||
if not hasattr(gunicorn_h1c, 'InvalidHeader'):
|
if not hasattr(gunicorn_h1c.H1CProtocol, 'asgi_headers'):
|
||||||
pytest.skip("gunicorn_h1c >= 0.6.0 required")
|
pytest.skip("gunicorn_h1c >= 0.6.2 required")
|
||||||
return request.param
|
return request.param
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user