From 3e448c2705d86e39e7e8ccf3c75bc3418c24aa2d Mon Sep 17 00:00:00 2001 From: Eliot Berriot Date: Thu, 7 Feb 2019 14:25:19 +0100 Subject: [PATCH] Fix #1240: ignore files when checking request size for multipart requests --- channels/http.py | 5 ++++- tests/test_http.py | 53 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/channels/http.py b/channels/http.py index 594fe8b96..a7358495e 100644 --- a/channels/http.py +++ b/channels/http.py @@ -120,8 +120,11 @@ def __init__(self, scope, body): # TODO: chunked bodies # Limit the maximum request data size that will be handled in-memory. + # but only for non-multipart requests, because files are handled + # differently by django, see #1240 if ( - settings.DATA_UPLOAD_MAX_MEMORY_SIZE is not None + self.content_type != "multipart/form-data" + and settings.DATA_UPLOAD_MAX_MEMORY_SIZE is not None and self._content_length > settings.DATA_UPLOAD_MAX_MEMORY_SIZE ): raise RequestDataTooBig( diff --git a/tests/test_http.py b/tests/test_http.py index 105186233..da4e8273b 100644 --- a/tests/test_http.py +++ b/tests/test_http.py @@ -189,22 +189,49 @@ def test_size_check_ignore_files(self): + b"My First Book\r\n" + b"--BOUNDARY\r\n" + b'Content-Disposition: form-data; name="pdf"; filename="book.pdf"\r\n\r\n' - + b"FAKEPDFBYTESGOHERE" + + b"FAKEPDFBYTESGOHERETHISISREALLYLONGBUTNOTUSEDTOCOMPUTETHESIZEOFTHEREQUEST" + b"--BOUNDARY--" ) - with override_settings(DATA_UPLOAD_MAX_MEMORY_SIZE=10): - AsgiRequest( - { - "http_version": "1.1", - "method": "POST", - "path": "/test/", - "headers": { - "content-type": b"multipart/form-data; boundary=BOUNDARY", - "content-length": str(len(body)).encode("ascii"), - }, + request = AsgiRequest( + { + "http_version": "1.1", + "method": "POST", + "path": "/test/", + "headers": { + "content-type": b"multipart/form-data; boundary=BOUNDARY", + "content-length": str(len(body)).encode("ascii"), }, - body, - ) + }, + body, + ) + with override_settings(DATA_UPLOAD_MAX_MEMORY_SIZE=60): + request.POST + + def test_size_check_ignore_files_but_honor_other_post_data(self): + body = ( + b"--BOUNDARY\r\n" + + b'Content-Disposition: form-data; name="title"\r\n\r\n' + + b"My First Book\r\n" + + b"--BOUNDARY\r\n" + + b'Content-Disposition: form-data; name="pdf"; filename="book.pdf"\r\n\r\n' + + b"FAKEPDFBYTESGOHERETHISISREALLYLONGBUTNOTUSEDTOCOMPUTETHESIZEOFTHEREQUEST" + + b"--BOUNDARY--" + ) + request = AsgiRequest( + { + "http_version": "1.1", + "method": "POST", + "path": "/test/", + "headers": { + "content-type": b"multipart/form-data; boundary=BOUNDARY", + "content-length": str(len(body)).encode("ascii"), + }, + }, + body, + ) + with override_settings(DATA_UPLOAD_MAX_MEMORY_SIZE=1): + with pytest.raises(RequestDataTooBig): + request.POST ### Handler tests