mirror of
https://github.com/frappe/gunicorn.git
synced 2026-07-03 19:21:29 +08:00
fix: reject asterisk-form request-target outside OPTIONS (RFC 9112 section 3.2.4)
The Python WSGI and ASGI parsers both accepted `GET *` and similar; RFC 9112 restricts asterisk-form to OPTIONS. Both now raise InvalidRequestLine. The fast (C) parser in gunicorn_h1c does not yet enforce this, so the fixture is marked python_only via a new sidecar flag honored by the WSGI and ASGI invalid-request harnesses.
This commit is contained in:
parent
2c57071675
commit
82d33d4c71
@ -456,6 +456,10 @@ class PythonProtocol:
|
||||
if not self._is_valid_method(self.method):
|
||||
raise InvalidRequestMethod(self.method.decode('latin-1'))
|
||||
|
||||
# RFC 9112 section 3.2.4: asterisk-form is only valid with OPTIONS.
|
||||
if self.path == b'*' and self.method != b'OPTIONS':
|
||||
raise InvalidRequestLine("Invalid request line")
|
||||
|
||||
# Parse version
|
||||
version = parts[2]
|
||||
if version == b'HTTP/1.1':
|
||||
|
||||
@ -807,6 +807,10 @@ class Request(Message):
|
||||
if len(self.uri) == 0:
|
||||
raise InvalidRequestLine(bytes_to_str(line_bytes))
|
||||
|
||||
# RFC 9112 section 3.2.4: asterisk-form is only valid with OPTIONS.
|
||||
if self.uri == "*" and self.method != "OPTIONS":
|
||||
raise InvalidRequestLine(bytes_to_str(line_bytes))
|
||||
|
||||
try:
|
||||
parts = split_request_uri(self.uri)
|
||||
except ValueError:
|
||||
|
||||
@ -7,3 +7,5 @@
|
||||
# rejected as an ill-formed request-line.
|
||||
from gunicorn.http.errors import InvalidRequestLine
|
||||
request = InvalidRequestLine
|
||||
# The C parser (gunicorn_h1c) does not yet enforce this rule.
|
||||
python_only = True
|
||||
|
||||
@ -78,5 +78,10 @@ def test_asgi_parser(fname, http_parser):
|
||||
):
|
||||
pytest.skip(f"Callback parser does not raise {expect.__name__}")
|
||||
|
||||
# Fixture-level opt-out for validations not (yet) implemented by the
|
||||
# fast (C) callback parser. The sidecar sets `python_only = True`.
|
||||
if http_parser == 'fast' and env.get('python_only'):
|
||||
pytest.skip("fixture marked python_only")
|
||||
|
||||
req = treq_asgi.badrequest(fname)
|
||||
req.check(cfg, expect, http_parser=http_parser)
|
||||
|
||||
@ -51,6 +51,11 @@ def test_http_parser(fname, http_parser):
|
||||
):
|
||||
pytest.skip(f"fast parser does not raise {expect.__name__}")
|
||||
|
||||
# Fixture-level opt-out for validations not (yet) implemented by
|
||||
# the C parser. The sidecar sets `python_only = True`.
|
||||
if env.get('python_only'):
|
||||
pytest.skip("fixture marked python_only")
|
||||
|
||||
# Determine acceptable exceptions (fast parser may raise alternates)
|
||||
if http_parser == 'fast' and expect in _FAST_PARSER_ALTERNATES:
|
||||
acceptable = (expect,) + _FAST_PARSER_ALTERNATES[expect]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user