@@ -337,6 +337,7 @@ async def _consume_body_async(
337337 ) -> None :
338338 async for chunk in source :
339339 dest .write (chunk )
340+ dest .end_stream ()
340341
341342 def __deepcopy__ (self , memo : Any ) -> "AWSCRTHTTPClient" :
342343 return AWSCRTHTTPClient (
@@ -354,30 +355,38 @@ def __init__(self) -> None:
354355 # will be much more efficient than a list.
355356 self ._chunks : deque [bytes ] = deque ()
356357 self ._closed = False
358+ self ._done = False
357359
358360 def read (self , size : int | None = - 1 ) -> bytes :
359361 if self ._closed :
360362 return b""
361363
362364 if len (self ._chunks ) == 0 :
365+ if self ._done :
366+ self ._closed = True
367+ return b""
368+
363369 # When the CRT recieves this, it'll try again later.
364370 raise BlockingIOError ("read" )
365371
366- chunk = self ._chunks .popleft ()
367- if size is None or size < 1 :
368- # We could compile all the chunks here instead of just returning
369- # the one, BUT the CRT will keep calling read until empty bytes
370- # are returned. So it's actually better to just return one chunk
371- # since combining them would have some potentially bad memory
372- # usage issues.
373- return chunk
374- else :
375- result = chunk [:size ]
376- remainder = chunk [size :]
372+ # We could compile all the chunks here instead of just returning
373+ # the one, BUT the CRT will keep calling read until empty bytes
374+ # are returned. So it's actually better to just return one chunk
375+ # since combining them would have some potentially bad memory
376+ # usage issues.
377+ result = self ._chunks .popleft ()
378+ if size is not None and size > 0 :
379+ remainder = result [size :]
380+ result = result [:size ]
377381 if remainder :
378382 self ._chunks .appendleft (remainder )
379383 return result
380384
385+ if self ._done and len (self ._chunks ) == 0 :
386+ self .close ()
387+
388+ return result
389+
381390 def read1 (self , size : int = - 1 ) -> bytes :
382391 return self .read (size )
383392
@@ -410,6 +419,10 @@ def closed(self) -> bool:
410419
411420 def close (self ) -> None :
412421 self ._closed = True
422+ self ._done = True
413423
414424 # Clear out the remaining chunks so that they don't sit around in memory.
415425 self ._chunks .clear ()
426+
427+ def end_stream (self ) -> None :
428+ self ._done = True
0 commit comments