]> git.ipfire.org Git - thirdparty/httpx.git/commitdiff
Support both zlib and deflate encodings (#758)
authorTom Christie <tom@tomchristie.com>
Tue, 14 Jan 2020 09:00:52 +0000 (09:00 +0000)
committerGitHub <noreply@github.com>
Tue, 14 Jan 2020 09:00:52 +0000 (09:00 +0000)
* Support both zlib and deflate encodings

* Helpful test docstrings

httpx/decoders.py
tests/test_decoders.py

index 75d980d3fa5c4ef21d1a044ec0785aa9459fbade..454ec4a11a194c6d0cba30f3e9bf49836273b06a 100644 (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:
index f320d9412e0884c86f06e18eee421c28bfe490bc..d9e82f702f9774621dd2594aa6ef28b38afe50ca 100644 (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)