diff --git a/CHANGES/3803.feature b/CHANGES/3803.feature new file mode 100644 index 0000000000..b2a4656196 --- /dev/null +++ b/CHANGES/3803.feature @@ -0,0 +1 @@ +Use Brotli instead of brotlipy diff --git a/aiohttp/http_parser.py b/aiohttp/http_parser.py index 3ee404f541..13f0c86b1f 100644 --- a/aiohttp/http_parser.py +++ b/aiohttp/http_parser.py @@ -6,7 +6,7 @@ import zlib from contextlib import suppress from enum import IntEnum -from typing import Generic, List, Optional, Tuple, Type, TypeVar, Union +from typing import Any, Generic, List, Optional, Tuple, Type, TypeVar, Union from multidict import CIMultiDict, CIMultiDictProxy, istr from yarl import URL @@ -804,6 +804,8 @@ def feed_data( class DeflateBuffer: """DeflateStream decompress stream and feed data into specified stream.""" + decompressor: Any + def __init__(self, out: StreamReader, encoding: Optional[str]) -> None: self.out = out self.size = 0 @@ -814,9 +816,27 @@ def __init__(self, out: StreamReader, encoding: Optional[str]) -> None: if not HAS_BROTLI: # pragma: no cover raise ContentEncodingError( "Can not decode content-encoding: brotli (br). " - "Please install `brotlipy`" + "Please install `Brotli`" ) - self.decompressor = brotli.Decompressor() + + class BrotliDecoder: + # Supports both 'brotlipy' and 'Brotli' packages + # since they share an import name. The top branches + # are for 'brotlipy' and bottom branches for 'Brotli' + def __init__(self) -> None: + self._obj = brotli.Decompressor() + + def decompress(self, data: bytes) -> bytes: + if hasattr(self._obj, "decompress"): + return self._obj.decompress(data) + return self._obj.process(data) + + def flush(self) -> bytes: + if hasattr(self._obj, "flush"): + return self._obj.flush() + return b"" + + self.decompressor = BrotliDecoder() else: zlib_mode = 16 + zlib.MAX_WBITS if encoding == "gzip" else zlib.MAX_WBITS self.decompressor = zlib.decompressobj(wbits=zlib_mode) diff --git a/docs/client_quickstart.rst b/docs/client_quickstart.rst index fe770243ec..e96dca453a 100644 --- a/docs/client_quickstart.rst +++ b/docs/client_quickstart.rst @@ -174,7 +174,7 @@ The ``gzip`` and ``deflate`` transfer-encodings are automatically decoded for you. You can enable ``brotli`` transfer-encodings support, -just install `brotlipy `_. +just install `brotli `_. JSON Request ============ diff --git a/docs/index.rst b/docs/index.rst index 13fe723b41..4091c00199 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -52,7 +52,7 @@ Installing speedups altogether ------------------------------ The following will get you ``aiohttp`` along with :term:`chardet`, -:term:`aiodns` and ``brotlipy`` in one bundle. No need to type +:term:`aiodns` and ``Brotli`` in one bundle. No need to type separate commands anymore! .. code-block:: bash diff --git a/requirements/base.txt b/requirements/base.txt index 23a5f40733..9b5a8ff848 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -6,7 +6,7 @@ async-generator==1.10 async-timeout==4.0.0a3 asynctest==0.13.0; python_version<"3.8" attrs==20.3.0 -brotlipy==0.7.0 +brotli==1.0.7 cchardet==2.1.7 chardet==3.0.4 frozenlist==1.1.1 diff --git a/setup.py b/setup.py index f21681333e..799c0fafa0 100644 --- a/setup.py +++ b/setup.py @@ -138,7 +138,7 @@ def read(f): extras_require={ "speedups": [ "aiodns", - "brotlipy", + "Brotli", "cchardet", ], },