Support both zlib and deflate encodings (#758)

* Support both zlib and deflate encodings

* Helpful test docstrings
This commit is contained in:
Tom Christie 2020-01-14 09:00:52 +00:00 committed by GitHub
parent 956129fbf7
commit 780d1843ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 1 deletions

View File

@ -45,12 +45,18 @@ class DeflateDecoder(Decoder):
"""
def __init__(self) -> None:
self.decompressor = zlib.decompressobj(-zlib.MAX_WBITS)
self.first_attempt = True
self.decompressor = zlib.decompressobj()
def decode(self, data: bytes) -> bytes:
was_first_attempt = self.first_attempt
self.first_attempt = False
try:
return self.decompressor.decompress(data)
except zlib.error as exc:
if was_first_attempt:
self.decompressor = zlib.decompressobj(-zlib.MAX_WBITS)
return self.decode(data)
raise DecodingError from exc
def flush(self) -> bytes:

View File

@ -18,6 +18,11 @@ REQUEST = httpx.Request("GET", "https://example.org")
def test_deflate():
"""
Deflate encoding may use either 'zlib' or 'deflate' in the wild.
https://stackoverflow.com/questions/1838699/how-can-i-decompress-a-gzip-stream-with-zlib#answer-22311297
"""
body = b"test 123"
compressor = zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS)
compressed_body = compressor.compress(body) + compressor.flush()
@ -29,6 +34,22 @@ def test_deflate():
assert response.content == body
def test_zlib():
"""
Deflate encoding may use either 'zlib' or 'deflate' in the wild.
https://stackoverflow.com/questions/1838699/how-can-i-decompress-a-gzip-stream-with-zlib#answer-22311297
"""
body = b"test 123"
compressed_body = zlib.compress(body)
headers = [(b"Content-Encoding", b"deflate")]
response = httpx.Response(
200, headers=headers, content=compressed_body, request=REQUEST
)
assert response.content == body
def test_gzip():
body = b"test 123"
compressor = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS | 16)