summaryrefslogtreecommitdiff
path: root/django/http/multipartparser.py
diff options
context:
space:
mode:
Diffstat (limited to 'django/http/multipartparser.py')
-rw-r--r--django/http/multipartparser.py36
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)