Skip to content

Commit b123d24

Browse files
committed
aiohttp: Reimplement ChunkedClientResponse.read
Correctly combines multiple chunks into a single response body. Signed-off-by: Rob Speed <speed.rob@gmail.com>
1 parent d0511a4 commit b123d24

File tree

1 file changed

+15
-17
lines changed

1 file changed

+15
-17
lines changed

python-ecosys/aiohttp/aiohttp/__init__.py

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -57,25 +57,23 @@ def __repr__(self):
5757

5858

5959
class ChunkedClientResponse(ClientResponse):
60-
def __init__(self, reader):
61-
self.content = reader
62-
self.chunk_size = 0
60+
async def read(self, sz=-1):
61+
data = bytearray(b"") # response data accumulator
6362

64-
async def read(self, sz=4 * 1024 * 1024):
65-
if self.chunk_size == 0:
63+
while True:
6664
l = await self.content.readline()
67-
l = l.split(b";", 1)[0]
68-
self.chunk_size = int(l, 16)
69-
if self.chunk_size == 0:
70-
# End of message
71-
sep = await self.content.readexactly(2)
72-
assert sep == b"\r\n"
73-
return b""
74-
data = await self.content.readexactly(min(sz, self.chunk_size))
75-
self.chunk_size -= len(data)
76-
if self.chunk_size == 0:
77-
sep = await self.content.readexactly(2)
78-
assert sep == b"\r\n"
65+
l = l.strip(b"\r\n") # remove CRLF
66+
l = l.split(b";", 1)[0] # ignore chunk-extensions
67+
chunk_size = int(l, 16)
68+
if chunk_size == 0:
69+
break
70+
71+
data.extend(await self.content.readexactly(chunk_size))
72+
73+
chunk_trailer = await self.content.readline()
74+
if chunk_trailer != b"\r\n":
75+
raise ValueError(f"Expected CRLF, got {chunk_trailer!r}")
76+
7977
return self._decode(data)
8078

8179
def __repr__(self):

0 commit comments

Comments
 (0)