Commit 6025562b authored by Vincent Pelletier's avatar Vincent Pelletier

http_wsgibase: Do not read entire chunks.

Chunk size is not bounded. So instead of remembering chunk tail, remember
how much there is to read in current chunk.
parent ef9e1e3a
......@@ -42,38 +42,45 @@ class ChunkedFile(ProxyFile):
def __init__(self, actual_file):
super(ChunkedFile, self).__init__(actual_file)
self._recv_buf = ''
self._chunk_remaining_length = 0
def read(self, length=None):
"""
Read chunked data.
"""
result = self._recv_buf
result = ''
if not self._at_eof:
readline = self.readline
read = self.__getattr__('read')
while length is None or len(result) < length:
chunk_header = readline(MAX_CHUNKED_HEADER_LENGTH + 1)
if len(chunk_header) > MAX_CHUNKED_HEADER_LENGTH:
raise ValueError('Chunked encoding header too long')
try:
chunk_length = int(chunk_header.split(' ', 1)[0], 16)
except ValueError:
raise ValueError('Invalid chunked encoding header')
if not chunk_length:
trailer = readline(MAX_CHUNKED_HEADER_LENGTH + 1)
if len(trailer) > MAX_CHUNKED_HEADER_LENGTH:
raise ValueError('Chunked encoding trailer too long')
self._at_eof = True
while True:
if self._chunk_remaining_length:
chunk_length = self._chunk_remaining_length
self._chunk_remaining_length = 0
else:
chunk_header = readline(MAX_CHUNKED_HEADER_LENGTH + 1)
if len(chunk_header) > MAX_CHUNKED_HEADER_LENGTH:
raise ValueError('Chunked encoding header too long')
try:
chunk_length = int(chunk_header.split(' ', 1)[0], 16)
except ValueError:
raise ValueError('Invalid chunked encoding header')
if not chunk_length:
trailer = readline(MAX_CHUNKED_HEADER_LENGTH + 1)
if len(trailer) > MAX_CHUNKED_HEADER_LENGTH:
raise ValueError('Chunked encoding trailer too long')
self._at_eof = True
break
if length is None:
to_read = chunk_length
else:
to_read = min(chunk_length, length - len(result))
result += read(to_read)
if to_read != chunk_length:
self._chunk_remaining_length = chunk_length - to_read
break
result += read(chunk_length)
if read(2) != '\r\n':
raise ValueError('Invalid chunked encoding separator')
if length is None:
self._recv_buf = ''
return result
self._recv_buf = result[length:]
return result[:length]
return result
class HookFirstReadFile(ProxyFile):
"""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment