This repository has been archived by the owner on Jan 13, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 193
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'nghttp2' into development
- Loading branch information
Showing
8 changed files
with
196 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,4 @@ omit = | |
hyper/compat.py | ||
hyper/httplib_compat.py | ||
hyper/ssl_compat.py | ||
hyper/http20/hpack_compat.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#!/bin/bash | ||
|
||
set -e | ||
set -x | ||
|
||
if [[ "$NGHTTP2" = true ]]; then | ||
# GCC 4.6 seems to cause problems, so go straight to 4.8. | ||
sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test | ||
sudo apt-get update | ||
sudo apt-get install g++-4.8 libstdc++-4.8-dev | ||
export CXX="g++-4.8" CC="gcc-4.8" | ||
$CC --version | ||
|
||
# Install nghttp2. Right now I haven't built a PPA for this so we have to | ||
# do it from source, which kinda sucks. First, install a ton of | ||
# prerequisite packages. | ||
sudo apt-get install autoconf automake autotools-dev libtool pkg-config \ | ||
zlib1g-dev libcunit1-dev libssl-dev libxml2-dev \ | ||
libevent-dev libjansson-dev libjemalloc-dev | ||
pip install cython | ||
|
||
# Now, download and install nghttp2's latest version. | ||
wget https://github.com/tatsuhiro-t/nghttp2/releases/download/v0.5.0/nghttp2-0.5.0.tar.gz | ||
tar -xzvf nghttp2-0.5.0.tar.gz | ||
cd nghttp2-0.5.0 | ||
autoreconf -i | ||
automake | ||
autoconf | ||
./configure --disable-threads | ||
make | ||
sudo make install | ||
|
||
# The makefile doesn't install into the active virtualenv. Install again. | ||
cd python | ||
python setup.py install | ||
cd ../.. | ||
|
||
# Let's try ldconfig. | ||
sudo sh -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/libnghttp2.conf' | ||
sudo ldconfig | ||
fi | ||
|
||
pip install . | ||
pip install -r test_requirements.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
hyper/http20/hpack_compat | ||
~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
Provides an abstraction layer over two HPACK implementations. | ||
Hyper has a pure-Python greenfield HPACK implementation that can be used on | ||
all Python platforms. However, this implementation is both slower and more | ||
memory-hungry than could be achieved with a C-language version. Additionally, | ||
nghttp2's HPACK implementation currently achieves better compression ratios | ||
than hyper's in almost all benchmarks. | ||
For those who care about efficiency and speed in HPACK, hyper allows you to | ||
use nghttp2's HPACK implementation instead of hyper's. This module detects | ||
whether the nghttp2 bindings are installed, and if they are it wraps them in | ||
a hyper-compatible API and uses them instead of its own. If not, it falls back | ||
to hyper's built-in Python bindings. | ||
""" | ||
import logging | ||
from .hpack import _to_bytes | ||
|
||
log = logging.getLogger(__name__) | ||
|
||
# Attempt to import nghttp2. | ||
try: | ||
import nghttp2 | ||
USE_NGHTTP2 = True | ||
log.debug("Using nghttp2's HPACK implementation.") | ||
except ImportError: | ||
USE_NGHTTP2 = False | ||
log.debug("Using hyper's pure-Python HPACK implementation.") | ||
|
||
if USE_NGHTTP2: | ||
class Encoder(object): | ||
""" | ||
An HPACK encoder object. This object takes HTTP headers and emits | ||
encoded HTTP/2 header blocks. | ||
""" | ||
def __init__(self): | ||
self._e = nghttp2.HDDeflater() | ||
|
||
@property | ||
def header_table_size(self): | ||
""" | ||
Returns the header table size. For the moment this isn't | ||
useful, so we don't use it. | ||
""" | ||
raise NotImplementedError() | ||
|
||
@header_table_size.setter | ||
def header_table_size(self, value): | ||
log.debug("Setting header table size to %d", value) | ||
self._e.change_table_size(value) | ||
|
||
def encode(self, headers, huffman=True): | ||
""" | ||
Encode the headers. The huffman parameter has no effect, it is | ||
simply present for compatibility. | ||
""" | ||
log.debug("HPACK encoding %s", headers) | ||
|
||
# Turn the headers into a list of tuples if possible. This is the | ||
# natural way to interact with them in HPACK. | ||
if isinstance(headers, dict): | ||
headers = headers.items() | ||
|
||
# Next, walk across the headers and turn them all into bytestrings. | ||
headers = [(_to_bytes(n), _to_bytes(v)) for n, v in headers] | ||
|
||
# Now, let nghttp2 do its thing. | ||
header_block = self._e.deflate(headers) | ||
|
||
return header_block | ||
|
||
class Decoder(object): | ||
""" | ||
An HPACK decoder object. | ||
""" | ||
def __init__(self): | ||
self._d = nghttp2.HDInflater() | ||
|
||
@property | ||
def header_table_size(self): | ||
""" | ||
Returns the header table size. For the moment this isn't | ||
useful, so we don't use it. | ||
""" | ||
raise NotImplementedError() | ||
|
||
@header_table_size.setter | ||
def header_table_size(self, value): | ||
log.debug("Setting header table size to %d", value) | ||
self._d.change_table_size(value) | ||
|
||
def decode(self, data): | ||
""" | ||
Takes an HPACK-encoded header block and decodes it into a header | ||
set. | ||
""" | ||
log.debug("Decoding %s", data) | ||
|
||
headers = self._d.inflate(data) | ||
return [(n.decode('utf-8'), v.decode('utf-8')) for n, v in headers] | ||
else: | ||
# Grab the built-in encoder and decoder. | ||
from .hpack import Encoder, Decoder |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters