mirror of
https://github.com/frappe/gunicorn.git
synced 2026-07-02 10:41:30 +08:00
Fix --limit-request-line 0 to mean unlimited
Per documentation, limit_request_line=0 means unlimited. The code was incorrectly treating 0 as "use default max" by checking <= 0 instead of < 0. For the fast C parser (gunicorn_h1c), which doesn't support 0 as unlimited, pass a large value (1MB) instead. This applies to both WSGI workers (http/message.py) and ASGI workers (asgi/protocol.py). Fixes #3563
This commit is contained in:
parent
d40a374547
commit
8d08aaa2cb
@ -419,12 +419,18 @@ class ASGIProtocol(asyncio.Protocol):
|
|||||||
else:
|
else:
|
||||||
parser_class = PythonProtocol
|
parser_class = PythonProtocol
|
||||||
|
|
||||||
|
# Handle limit_request_line=0 (unlimited per documentation)
|
||||||
|
# PythonProtocol handles 0 correctly, but C parser needs a large value
|
||||||
|
limit_request_line = self.cfg.limit_request_line
|
||||||
|
if limit_request_line == 0 and parser_class != PythonProtocol:
|
||||||
|
limit_request_line = 1024 * 1024 # 1MB for C parser
|
||||||
|
|
||||||
# Create parser with callbacks and limit parameters (both parsers support them)
|
# Create parser with callbacks and limit parameters (both parsers support them)
|
||||||
self._callback_parser = parser_class(
|
self._callback_parser = parser_class(
|
||||||
on_headers_complete=self._on_headers_complete,
|
on_headers_complete=self._on_headers_complete,
|
||||||
on_body=self._on_body,
|
on_body=self._on_body,
|
||||||
on_message_complete=self._on_message_complete,
|
on_message_complete=self._on_message_complete,
|
||||||
limit_request_line=self.cfg.limit_request_line,
|
limit_request_line=limit_request_line,
|
||||||
limit_request_fields=self.cfg.limit_request_fields,
|
limit_request_fields=self.cfg.limit_request_fields,
|
||||||
limit_request_field_size=self.cfg.limit_request_field_size,
|
limit_request_field_size=self.cfg.limit_request_field_size,
|
||||||
permit_unconventional_http_method=self.cfg.permit_unconventional_http_method,
|
permit_unconventional_http_method=self.cfg.permit_unconventional_http_method,
|
||||||
|
|||||||
@ -387,11 +387,19 @@ class Request(Message):
|
|||||||
self.query = None
|
self.query = None
|
||||||
self.fragment = None
|
self.fragment = None
|
||||||
|
|
||||||
# get max request line size
|
# get max request line size (0 means unlimited per documentation)
|
||||||
self.limit_request_line = cfg.limit_request_line
|
self.limit_request_line = cfg.limit_request_line
|
||||||
if (self.limit_request_line <= 0
|
if self.limit_request_line < 0:
|
||||||
or self.limit_request_line >= MAX_REQUEST_LINE):
|
|
||||||
self.limit_request_line = MAX_REQUEST_LINE
|
self.limit_request_line = MAX_REQUEST_LINE
|
||||||
|
# For fast parser: use large value when unlimited (0), since C parser
|
||||||
|
# doesn't support 0 as unlimited. 1MB should be more than enough.
|
||||||
|
if self.limit_request_line == 0:
|
||||||
|
self._fast_limit_request_line = 1024 * 1024 # 1MB
|
||||||
|
elif self.limit_request_line >= MAX_REQUEST_LINE:
|
||||||
|
self._fast_limit_request_line = MAX_REQUEST_LINE
|
||||||
|
self.limit_request_line = MAX_REQUEST_LINE
|
||||||
|
else:
|
||||||
|
self._fast_limit_request_line = self.limit_request_line
|
||||||
|
|
||||||
self.req_number = req_number
|
self.req_number = req_number
|
||||||
self.proxy_protocol_info = None
|
self.proxy_protocol_info = None
|
||||||
@ -433,10 +441,11 @@ class Request(Message):
|
|||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
# Pass all limit parameters to C parser
|
# Pass all limit parameters to C parser
|
||||||
|
# Use _fast_limit_request_line which handles 0=unlimited
|
||||||
result = _fast_parser_module.parse_request(
|
result = _fast_parser_module.parse_request(
|
||||||
data,
|
data,
|
||||||
last_len=last_len,
|
last_len=last_len,
|
||||||
limit_request_line=self.limit_request_line,
|
limit_request_line=self._fast_limit_request_line,
|
||||||
limit_request_fields=self.limit_request_fields,
|
limit_request_fields=self.limit_request_fields,
|
||||||
limit_request_field_size=self.limit_request_field_size,
|
limit_request_field_size=self.limit_request_field_size,
|
||||||
permit_unconventional_http_method=self.cfg.permit_unconventional_http_method,
|
permit_unconventional_http_method=self.cfg.permit_unconventional_http_method,
|
||||||
@ -447,7 +456,7 @@ class Request(Message):
|
|||||||
last_len = len(data)
|
last_len = len(data)
|
||||||
self.read_into(unreader, buf)
|
self.read_into(unreader, buf)
|
||||||
data = bytes(buf)
|
data = bytes(buf)
|
||||||
if len(data) > self.max_buffer_headers + self.limit_request_line:
|
if len(data) > self.max_buffer_headers + self._fast_limit_request_line:
|
||||||
raise LimitRequestHeaders("max buffer headers")
|
raise LimitRequestHeaders("max buffer headers")
|
||||||
except _fast_parser_module.LimitRequestLine as e:
|
except _fast_parser_module.LimitRequestLine as e:
|
||||||
raise LimitRequestLine(str(e))
|
raise LimitRequestLine(str(e))
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -1,11 +0,0 @@
|
|||||||
#
|
|
||||||
# This file is part of gunicorn released under the MIT license.
|
|
||||||
# See the NOTICE for more information.
|
|
||||||
|
|
||||||
from gunicorn.config import Config
|
|
||||||
from gunicorn.http.errors import LimitRequestLine
|
|
||||||
|
|
||||||
cfg = Config()
|
|
||||||
# Setting limit_request_line=0 should use default max (8190)
|
|
||||||
cfg.set('limit_request_line', 0)
|
|
||||||
request = LimitRequestLine
|
|
||||||
Loading…
x
Reference in New Issue
Block a user