Skip to content
This repository has been archived by the owner on Jan 13, 2021. It is now read-only.

Commit

Permalink
Merge pull request #368 from viranch/brotli
Browse files Browse the repository at this point in the history
Add support for brotli compression
  • Loading branch information
Lukasa authored Nov 29, 2017
2 parents 98d9e5f + 1026313 commit 4b522f5
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 1 deletion.
3 changes: 3 additions & 0 deletions hyper/http11/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import logging
import weakref
import zlib
import brotli

from ..common.decoder import DeflateDecoder
from ..common.exceptions import ChunkedDecodeError, InvalidResponseError
Expand Down Expand Up @@ -88,6 +89,8 @@ def __init__(self, code, reason, headers, sock, connection=None,
# http://stackoverflow.com/a/2695466/1401686
if b'gzip' in self.headers.get(b'content-encoding', []):
self._decompressobj = zlib.decompressobj(16 + zlib.MAX_WBITS)
elif b'br' in self.headers.get(b'content-encoding', []):
self._decompressobj = brotli.Decompressor()
elif b'deflate' in self.headers.get(b'content-encoding', []):
self._decompressobj = DeflateDecoder()
else:
Expand Down
2 changes: 2 additions & 0 deletions hyper/http20/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"""
import logging
import zlib
import brotli

from ..common.decoder import DeflateDecoder
from ..common.headers import HTTPHeaderMap
Expand All @@ -31,6 +32,7 @@ def strip_headers(headers):

decompressors = {
b'gzip': lambda: zlib.decompressobj(16 + zlib.MAX_WBITS),
b'br': brotli.Decompressor,
b'deflate': DeflateDecoder
}

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def run_tests(self):
'Programming Language :: Python :: Implementation :: CPython',
],
install_requires=[
'h2>=2.4,<3.0,!=2.5.0', 'hyperframe>=3.2,<4.0', 'rfc3986>=1.1.0,<2.0'
'h2>=2.4,<3.0,!=2.5.0', 'hyperframe>=3.2,<4.0', 'rfc3986>=1.1.0,<2.0', 'brotlipy>=0.7.0,<1.0'
],
tests_require=['pytest', 'requests', 'mock'],
cmdclass={'test': PyTest},
Expand Down
11 changes: 11 additions & 0 deletions test/test_http11.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"""
import os
import zlib
import brotli

from collections import namedtuple
from io import BytesIO, StringIO
Expand Down Expand Up @@ -644,6 +645,16 @@ def test_response_transparently_decrypts_gzip(self):

assert r.read() == b'this is test data'

def test_response_transparently_decrypts_brotli(self):
d = DummySocket()
headers = {b'content-encoding': [b'br'], b'connection': [b'close']}
r = HTTP11Response(200, 'OK', headers, d, None)

body = brotli.compress(b'this is test data')
d._buffer = BytesIO(body)

assert r.read() == b'this is test data'

def test_response_transparently_decrypts_real_deflate(self):
d = DummySocket()
headers = {
Expand Down
10 changes: 10 additions & 0 deletions test/test_hyper.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import pytest
import socket
import zlib
import brotli
from io import BytesIO

TEST_DIR = os.path.abspath(os.path.dirname(__file__))
Expand Down Expand Up @@ -1088,6 +1089,15 @@ def test_response_transparently_decrypts_gzip(self):

assert resp.read() == b'this is test data'

def test_response_transparently_decrypts_brotli(self):
headers = HTTPHeaderMap(
[(':status', '200'), ('content-encoding', 'br')]
)
body = brotli.compress(b'this is test data')
resp = HTTP20Response(headers, DummyStream(body))

assert resp.read() == b'this is test data'

def test_response_transparently_decrypts_real_deflate(self):
headers = HTTPHeaderMap(
[(':status', '200'), ('content-encoding', 'deflate')]
Expand Down

0 comments on commit 4b522f5

Please sign in to comment.