From a7424ddf490fc51244d427543cc9683b5427102b Mon Sep 17 00:00:00 2001
From: Felix Yan <felixonmars@archlinux.org>
Date: Fri, 19 Jul 2019 21:32:55 +0800
Subject: [PATCH] Use Brotli instead of brotlipy (#3803)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

brotlipy is stuck at brotli 0.6 and upstream is inactive. Let's switch
to the official binding which is up-to-date.

(rebased for 3.7.x by Michał Górny)
---
 aiohttp/http_parser.py     | 25 +++++++++++++++++++++----
 docs/client_quickstart.rst |  2 +-
 docs/index.rst             |  2 +-
 setup.py                   |  2 +-
 4 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/aiohttp/http_parser.py b/aiohttp/http_parser.py
index 71ba815a..56ecead4 100644
--- a/aiohttp/http_parser.py
+++ b/aiohttp/http_parser.py
@@ -821,10 +821,27 @@ class DeflateBuffer:
         if encoding == "br":
             if not HAS_BROTLI:  # pragma: no cover
                 raise ContentEncodingError(
-                    "Can not decode content-encoding: brotli (br). "
-                    "Please install `brotlipy`"
-                )
-            self.decompressor = brotli.Decompressor()
+                    'Can not decode content-encoding: brotli (br). '
+                    'Please install `Brotli`')
+
+            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()  # type: Any
         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 95588cb6..b9146584 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 <https://github.com/python-hyper/brotlipy>`_.
+just install  `Brotli <https://pypi.org/project/Brotli>`_.
 
 JSON Request
 ============
diff --git a/docs/index.rst b/docs/index.rst
index 13fe723b..4091c001 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/setup.py b/setup.py
index 54462ba7..7a184817 100644
--- a/setup.py
+++ b/setup.py
@@ -137,7 +137,7 @@ args = dict(
     extras_require={
         "speedups": [
             "aiodns",
-            "brotlipy",
+            "Brotli",
             "cchardet",
         ],
     },
-- 
2.32.0

