mirror of
https://github.com/frappe/gunicorn.git
synced 2026-07-01 10:11:30 +08:00
test: parametrize smuggling regression across python and fast parsers
The previous test forced http_parser='python' to avoid a hard dependency on gunicorn_h1c. Now run the same scenario under both parser implementations so the smuggling guard is exercised on every supported request-line/header path.
This commit is contained in:
parent
4e4a60ee77
commit
35c6a2abef
@ -17,6 +17,7 @@ gate can read it. See the commit that added this test for the fix.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
@ -83,12 +84,11 @@ class _Log:
|
||||
return False
|
||||
|
||||
|
||||
def _build_worker(loop, app):
|
||||
def _build_worker(loop, app, http_parser):
|
||||
cfg = Config()
|
||||
cfg.set('keepalive', 2)
|
||||
cfg.set('timeout', 30)
|
||||
# Force the Python parser so the test does not depend on gunicorn_h1c.
|
||||
cfg.set('http_parser', 'python')
|
||||
cfg.set('http_parser', http_parser)
|
||||
|
||||
class _W:
|
||||
pass
|
||||
@ -104,14 +104,29 @@ def _build_worker(loop, app):
|
||||
return w
|
||||
|
||||
|
||||
@pytest.fixture(params=["python", "fast"])
|
||||
def http_parser(request):
|
||||
"""Parametrize the smuggling test across both parser implementations."""
|
||||
if request.param == "fast":
|
||||
if hasattr(sys, "pypy_version_info"):
|
||||
pytest.skip("gunicorn_h1c not supported on PyPy")
|
||||
gunicorn_h1c = pytest.importorskip("gunicorn_h1c")
|
||||
if not hasattr(gunicorn_h1c.H1CProtocol, "asgi_headers"):
|
||||
pytest.skip("gunicorn_h1c >= 0.6.2 required")
|
||||
return request.param
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_keepalive_refused_when_first_body_is_partial():
|
||||
async def test_keepalive_refused_when_first_body_is_partial(http_parser):
|
||||
"""Two pipelined requests on the same connection. The first POST
|
||||
advertises Content-Length: 100 but the client only sends 10 body
|
||||
bytes. The app returns 200 without consuming the body. The
|
||||
transport MUST close instead of serving a second response from the
|
||||
residual bytes (which would be the second request the attacker
|
||||
pipelined behind the short body).
|
||||
|
||||
Run under both the Python parser and the C parser (gunicorn_h1c) so
|
||||
the smuggling guard is verified end-to-end on every supported path.
|
||||
"""
|
||||
|
||||
async def app(scope, receive, send):
|
||||
@ -127,7 +142,7 @@ async def test_keepalive_refused_when_first_body_is_partial():
|
||||
})
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
worker = _build_worker(loop, app)
|
||||
worker = _build_worker(loop, app, http_parser)
|
||||
protocol = ASGIProtocol(worker)
|
||||
transport = _FakeTransport()
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user