diff --git a/CHANGES/3123.bugfix b/CHANGES/3123.bugfix new file mode 100644 index 00000000000..0b24050a01e --- /dev/null +++ b/CHANGES/3123.bugfix @@ -0,0 +1 @@ +Do not hang on `206 Partial Content` response with `Content-Encoding: gzip` diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index ea34e13be7d..ec8fd3e54d6 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -152,6 +152,7 @@ Panagiotis Kolokotronis Pankaj Pandey Pau Freixes Paul Colomiets +Paulius Šileikis Paulus Schoutsen Pavel Kamaev Pawel Miech diff --git a/aiohttp/http_parser.py b/aiohttp/http_parser.py index 23a4c5f3e8f..ab6d5c4f544 100644 --- a/aiohttp/http_parser.py +++ b/aiohttp/http_parser.py @@ -662,7 +662,7 @@ def feed_eof(self): if chunk or self.size > 0: self.out.feed_data(chunk, len(chunk)) - if self.encoding != 'br' and not self.decompressor.eof: + if self.encoding == 'deflate' and not self.decompressor.eof: raise ContentEncodingError('deflate') self.out.feed_eof() diff --git a/tests/test_http_parser.py b/tests/test_http_parser.py index 14a742f8bad..df4350d9cb3 100644 --- a/tests/test_http_parser.py +++ b/tests/test_http_parser.py @@ -902,7 +902,7 @@ def test_feed_eof(self, stream): assert [b'line'] == list(d for d, _ in buf._buffer) assert buf._eof - def test_feed_eof_err(self, stream): + def test_feed_eof_err_deflate(self, stream): buf = aiohttp.FlowControlDataQueue(stream) dbuf = DeflateBuffer(buf, 'deflate') @@ -913,6 +913,28 @@ def test_feed_eof_err(self, stream): with pytest.raises(http_exceptions.ContentEncodingError): dbuf.feed_eof() + def test_feed_eof_no_err_gzip(self, stream): + buf = aiohttp.FlowControlDataQueue(stream) + dbuf = DeflateBuffer(buf, 'gzip') + + dbuf.decompressor = mock.Mock() + dbuf.decompressor.flush.return_value = b'line' + dbuf.decompressor.eof = False + + dbuf.feed_eof() + assert [b'line'] == list(d for d, _ in buf._buffer) + + def test_feed_eof_no_err_brotli(self, stream): + buf = aiohttp.FlowControlDataQueue(stream) + dbuf = DeflateBuffer(buf, 'br') + + dbuf.decompressor = mock.Mock() + dbuf.decompressor.flush.return_value = b'line' + dbuf.decompressor.eof = False + + dbuf.feed_eof() + assert [b'line'] == list(d for d, _ in buf._buffer) + def test_empty_body(self, stream): buf = aiohttp.FlowControlDataQueue(stream) dbuf = DeflateBuffer(buf, 'deflate')