Skip to content

Commit

Permalink
Fix HttpPayloadParser dealing with chunked response (aio-libs#4630)
Browse files Browse the repository at this point in the history
HttpPayloadParser waits for trailers indefinitely even if there are no trailers
at the response. This happens when only the last CRLF or the last LF are sent
via separate TCP segment.

When the connection is keep alive and if this bug occurs then users experience
response timeout. But this problem is not exposed when keep alive is disabled
because .feed_eof is called.
  • Loading branch information
rhdxmr committed Jun 7, 2020
1 parent 385b03e commit 0c389b1
Showing 1 changed file with 19 additions and 5 deletions.
24 changes: 19 additions & 5 deletions aiohttp/http_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -668,12 +668,26 @@ def feed_data(self,
# we should get another \r\n otherwise
# trailers needs to be skiped until \r\n\r\n
if self._chunk == ChunkState.PARSE_MAYBE_TRAILERS:
if chunk[:2] == SEP:
# end of stream
self.payload.feed_eof()
return True, chunk[2:]
if len(chunk) >= 2:
if chunk[:2] == SEP:
# end of stream
self.payload.feed_eof()
return True, chunk[2:]
else:
self._chunk = ChunkState.PARSE_TRAILERS
else:
self._chunk = ChunkState.PARSE_TRAILERS
# Both CR and LF, or only LF may not be received
# yet. It is expected that CRLF or LF will be shown at
# the very first byte next time, otherwise trailers
# should come.
# The last CRLF which marks the end of response
# might not be contained in the same TCP segment which
# delivered the size indicator.
if not chunk or chunk[:1] == SEP[:1]:
self._chunk_tail = chunk
return False, b''
else:
self._chunk = ChunkState.PARSE_TRAILERS

# read and discard trailer up to the CRLF terminator
if self._chunk == ChunkState.PARSE_TRAILERS:
Expand Down

0 comments on commit 0c389b1

Please sign in to comment.