Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport brotli #5335

Merged
merged 1 commit into from Dec 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES/3803.feature
@@ -0,0 +1 @@
Use Brotli instead of brotlipy
26 changes: 23 additions & 3 deletions aiohttp/http_parser.py
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion docs/client_quickstart.rst
Expand Up @@ -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 <https://github.com/python-hyper/brotlipy>`_.
just install `brotli <https://github.com/python-hyper/Brotli>`_.

JSON Request
============
Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion requirements/base.txt
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Expand Up @@ -138,7 +138,7 @@ def read(f):
extras_require={
"speedups": [
"aiodns",
"brotlipy",
"Brotli",
"cchardet",
],
},
Expand Down