diff options
author | David Lord <davidism@gmail.com> | 2023-04-28 06:30:17 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-28 06:30:17 -0700 |
commit | 5c32263a2ba135bad8b085087f4035b3c135f67e (patch) | |
tree | 841ed0054abe7f844a8b9c3bcd66b6b09a0cb6dc | |
parent | d34dc8557d5b2e7624c625a30dd5a9bbedf93f93 (diff) | |
parent | 06e8df4f450c1696aead4a8ebc5ea427a62f7306 (diff) | |
download | werkzeug-5c32263a2ba135bad8b085087f4035b3c135f67e.tar.gz |
max_content_length only with wsgi.input_terminated (#2671)
-rw-r--r-- | CHANGES.rst | 2 | ||||
-rw-r--r-- | src/werkzeug/wsgi.py | 20 |
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 |