summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lord <davidism@gmail.com>2023-04-28 06:30:17 -0700
committerGitHub <noreply@github.com>2023-04-28 06:30:17 -0700
commit5c32263a2ba135bad8b085087f4035b3c135f67e (patch)
tree841ed0054abe7f844a8b9c3bcd66b6b09a0cb6dc
parentd34dc8557d5b2e7624c625a30dd5a9bbedf93f93 (diff)
parent06e8df4f450c1696aead4a8ebc5ea427a62f7306 (diff)
downloadwerkzeug-5c32263a2ba135bad8b085087f4035b3c135f67e.tar.gz
max_content_length only with wsgi.input_terminated (#2671)
-rw-r--r--CHANGES.rst2
-rw-r--r--src/werkzeug/wsgi.py20
2 files changed, 14 insertions, 8 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index cc01125a..e47232fe 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -6,6 +6,8 @@ Version 2.3.2
Unreleased
- Parse the cookie ``Expires`` attribute correctly in the test client. :issue:`2669`
+- ``max_content_length`` can only be enforced on streaming requests if the server
+ sets ``wsgi.input_terminated``. :issue:`2668`
Version 2.3.1
diff --git a/src/werkzeug/wsgi.py b/src/werkzeug/wsgi.py
index f5bb2d13..8c50ecdd 100644
--- a/src/werkzeug/wsgi.py
+++ b/src/werkzeug/wsgi.py
@@ -147,9 +147,9 @@ def get_input_stream(
server handles terminating the stream, so it is safe to read directly. For example,
a server that knows how to handle chunked requests safely would set this.
- If ``max_content_length`` is set, that limit is used even if ``Content-Length`` or
- ``wsgi.input_terminated`` are set. If none of these are set, then an empty stream is
- returned unless the user explicitly disables this safe fallback.
+ If ``max_content_length`` is set, it can be enforced on streams if
+ ``wsgi.input_terminated`` is set. Otherwise, an empty stream is returned unless the
+ user explicitly disables this safe fallback.
If the limit is reached before the underlying stream is exhausted (such as a file
that is too large, or an infinite stream), the remaining contents of the stream
@@ -173,14 +173,18 @@ def get_input_stream(
if content_length is not None and max_content_length is not None:
if content_length > max_content_length:
raise RequestEntityTooLarge()
- elif max_content_length is not None:
- return t.cast(
- t.IO[bytes], LimitedStream(stream, max_content_length, is_max=True)
- )
# A WSGI server can set this to indicate that it terminates the input stream. In
- # that case the stream is safe without wrapping.
+ # that case the stream is safe without wrapping, or can enforce a max length.
if "wsgi.input_terminated" in environ:
+ if max_content_length is not None:
+ # If this is moved above, it can cause the stream to hang if a read attempt
+ # is made when the client sends no data. For example, the development server
+ # does not handle buffering except for chunked encoding.
+ return t.cast(
+ t.IO[bytes], LimitedStream(stream, max_content_length, is_max=True)
+ )
+
return stream
# No limit given, return an empty stream unless the user explicitly allows the