diff options
Diffstat (limited to 'django/http/multipartparser.py')
| -rw-r--r-- | django/http/multipartparser.py | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py index 5ab63455ef..dfd406c35e 100644 --- a/django/http/multipartparser.py +++ b/django/http/multipartparser.py @@ -41,6 +41,7 @@ RAW = "raw" FILE = "file" FIELD = "field" FIELD_TYPES = frozenset([FIELD, RAW]) +MAX_TOTAL_HEADER_SIZE = 1024 class MultiPartParser: @@ -682,21 +683,30 @@ def parse_boundary_stream(stream, max_header_size): """ Parse one and exactly one stream that encapsulates a boundary. """ - # Stream at beginning of header, look for end of header - # and parse it if found. The header must fit within one - # chunk. - chunk = stream.read(max_header_size) - # 'find' returns the top of these four bytes, so we'll - # need to munch them later to prevent them from polluting - # the payload. - header_end = chunk.find(b"\r\n\r\n") + # Look for the end of headers and if not found extend the search to double + # the size up to the MAX_TOTAL_HEADER_SIZE. + headers_chunk_size = 1024 + while True: + if headers_chunk_size > max_header_size: + raise MultiPartParserError("Request max total header size exceeded.") - if header_end == -1: - # we find no header, so we just mark this fact and pass on - # the stream verbatim + # Stream at beginning of header, look for end of header and parse it if + # found. The header must fit within one chunk. + chunk = stream.read(headers_chunk_size) + # 'find' returns the top of these four bytes, so munch them later to + # prevent them from polluting the payload. + header_end = chunk.find(b"\r\n\r\n") + if header_end != -1: + break + + # Find no header, mark this fact and pass on the stream verbatim. stream.unget(chunk) - return (RAW, {}, stream) + # No more data to read. + if len(chunk) < headers_chunk_size: + return (RAW, {}, stream) + # Double the chunk size. + headers_chunk_size *= 2 header = chunk[:header_end] @@ -740,4 +750,4 @@ class Parser: boundarystream = InterBoundaryIter(self._stream, self._separator) for sub_stream in boundarystream: # Iterate over each part - yield parse_boundary_stream(sub_stream, 1024) + yield parse_boundary_stream(sub_stream, MAX_TOTAL_HEADER_SIZE) |
