Limit body framing fix to incomplete chunked trailers

This commit is contained in:
Hulk authored and Niko1221 committed 2026-10-09 03:04:21 +02:00
1 parent d467b3d2bb
commit 8c6b1cc5b5
2 files changed
+5 -12

No files matched your search

+3 -6
View File
@@ -4197,7 +4197,7 @@ def body_limit() -> int:
class BadBody(Exception):
"""A request body that cannot be read (malformed, incomplete or oversized): the status and the sentence."""
"""A request body that cannot be read (a malformed or oversized chunked body): the status and the sentence."""
def __init__(self, status: int, message: str):
super().__init__(message)
@@ -4289,10 +4289,7 @@ def make_handler(svc: Service):
self.close_connection = True # the body is not read: the connection ends with the answer
raise BadBody(413, f"the request body is larger than {limit >> 20} MiB "
"(STRATA_MAX_BODY_MIB raises the limit)")
body = self.rfile.read(length)
if len(body) != length:
raise BadBody(400, "the request body ended early")
return body
return self.rfile.read(length)
def _drain_body(self):
"""An answer sent before the body was read (a 401, a 403, /load, a method with no handler) must not close
@@ -4603,7 +4600,7 @@ def make_handler(svc: Service):
def do_POST(self):
try:
self._post()
except BadBody as e: # a malformed, incomplete or oversized body
except BadBody as e: # #893: a malformed or oversized chunked body
self._json(e.status, {"error": {"type": "invalid_request_error", "message": str(e)}})
def _post(self):
+2 -6
View File
@@ -1,6 +1,6 @@
"""#893 / #894: a request body sent as Transfer-Encoding: chunked (a relay or proxy) is decoded, on every route that
reads a body; a malformed or oversized one is a 400 / 413, not an empty body. Incomplete framing must not apply an
otherwise valid JSON body, for either Content-Length or chunked requests.
reads a body; a malformed or oversized one is a 400 / 413, not an empty body. Incomplete chunked framing must not
apply an otherwise valid JSON body.
python -m unittest serve.test_chunked_body -v
"""
@@ -109,10 +109,6 @@ class ChunkedBody(unittest.TestCase):
status, got = self.send(head, body)
self.assertEqual((status, self.svc.shared), (400, before), got)
def test_a_short_content_length_body_does_not_change_settings(self):
body = json.dumps({"defaults": {"temperature": 0.5}}).encode()
self.assert_settings_body_rejected(b"Content-Length: %d" % (len(body) + 1) + CRLF, body)
def test_incomplete_chunked_trailers_do_not_change_settings(self):
body = json.dumps({"defaults": {"temperature": 0.5}}).encode()
prefix = chunked(body)[:-len(CRLF)] # the zero chunk, without the terminating blank line