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): ...@@ -42,38 +42,45 @@ class ChunkedFile(ProxyFile):
def __init__(self, actual_file): def __init__(self, actual_file):
super(ChunkedFile, self).__init__(actual_file) super(ChunkedFile, self).__init__(actual_file)
self._recv_buf = '' self._chunk_remaining_length = 0
def read(self, length=None): def read(self, length=None):
""" """
Read chunked data. Read chunked data.
""" """
result = self._recv_buf result = ''
if not self._at_eof: if not self._at_eof:
readline = self.readline readline = self.readline
read = self.__getattr__('read') read = self.__getattr__('read')
while length is None or len(result) < length: while True:
chunk_header = readline(MAX_CHUNKED_HEADER_LENGTH + 1) if self._chunk_remaining_length:
if len(chunk_header) > MAX_CHUNKED_HEADER_LENGTH: chunk_length = self._chunk_remaining_length
raise ValueError('Chunked encoding header too long') self._chunk_remaining_length = 0
try: else:
chunk_length = int(chunk_header.split(' ', 1)[0], 16) chunk_header = readline(MAX_CHUNKED_HEADER_LENGTH + 1)
except ValueError: if len(chunk_header) > MAX_CHUNKED_HEADER_LENGTH:
raise ValueError('Invalid chunked encoding header') raise ValueError('Chunked encoding header too long')
if not chunk_length: try:
trailer = readline(MAX_CHUNKED_HEADER_LENGTH + 1) chunk_length = int(chunk_header.split(' ', 1)[0], 16)
if len(trailer) > MAX_CHUNKED_HEADER_LENGTH: except ValueError:
raise ValueError('Chunked encoding trailer too long') raise ValueError('Invalid chunked encoding header')
self._at_eof = True 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 break
result += read(chunk_length)
if read(2) != '\r\n': if read(2) != '\r\n':
raise ValueError('Invalid chunked encoding separator') raise ValueError('Invalid chunked encoding separator')
if length is None: return result
self._recv_buf = ''
return result
self._recv_buf = result[length:]
return result[:length]
class HookFirstReadFile(ProxyFile): 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