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

Commit

Permalink
adding HTTP version flags to connections and responses
Browse files Browse the repository at this point in the history
  • Loading branch information
nateprewitt committed Dec 2, 2016
1 parent 1f8e53f commit e76f185
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 4 deletions.
10 changes: 10 additions & 0 deletions hyper/common/util.py
Expand Up @@ -5,6 +5,8 @@
General utility functions for use with hyper.
"""
from enum import Enum

from hyper.compat import unicode, bytes, imap
from ..packages.rfc3986.uri import URIReference
from ..compat import is_py3
Expand Down Expand Up @@ -57,3 +59,11 @@ def to_native_string(string, encoding='utf-8'):
return string

return string.decode(encoding) if is_py3 else string.encode(encoding)


class HTTPVersion(Enum):
"""
Collection of all HTTP versions used in hyper.
"""
http11 = "HTTP/1.1"
http20 = "HTTP/2"
5 changes: 4 additions & 1 deletion hyper/http11/connection.py
Expand Up @@ -20,7 +20,7 @@
from ..common.bufsocket import BufferedSocket
from ..common.exceptions import TLSUpgrade, HTTPUpgrade
from ..common.headers import HTTPHeaderMap
from ..common.util import to_bytestring, to_host_port_tuple
from ..common.util import to_bytestring, to_host_port_tuple, HTTPVersion
from ..compat import bytes

# We prefer pycohttpparser to the pure-Python interpretation
Expand Down Expand Up @@ -56,6 +56,9 @@ class HTTP11Connection(object):
and one also isn't provided in the ``proxy`` parameter,
defaults to 8080.
"""

version = HTTPVersion.http11

def __init__(self, host, port=None, secure=None, ssl_context=None,
proxy_host=None, proxy_port=None, **kwargs):
if port is None:
Expand Down
4 changes: 4 additions & 0 deletions hyper/http11/response.py
Expand Up @@ -13,6 +13,7 @@
from ..common.decoder import DeflateDecoder
from ..common.exceptions import ChunkedDecodeError, InvalidResponseError
from ..common.exceptions import ConnectionResetError
from ..common.util import HTTPVersion

log = logging.getLogger(__name__)

Expand All @@ -23,6 +24,9 @@ class HTTP11Response(object):
provides access to the response headers and the entity body. The response
is an iterable object and can be used in a with statement.
"""

version = HTTPVersion.http11

def __init__(self, code, reason, headers, sock, connection=None):
#: The reason phrase returned by the server.
self.reason = reason
Expand Down
7 changes: 6 additions & 1 deletion hyper/http20/connection.py
Expand Up @@ -14,7 +14,9 @@
from ..common.exceptions import ConnectionResetError
from ..common.bufsocket import BufferedSocket
from ..common.headers import HTTPHeaderMap
from ..common.util import to_host_port_tuple, to_native_string, to_bytestring
from ..common.util import (
to_host_port_tuple, to_native_string, to_bytestring, HTTPVersion
)
from ..compat import unicode, bytes
from .stream import Stream
from .response import HTTP20Response, HTTP20Push
Expand Down Expand Up @@ -91,6 +93,9 @@ class HTTP20Connection(object):
and one also isn't provided in the ``proxy`` parameter, defaults to
8080.
"""

version = HTTPVersion.http20

def __init__(self, host, port=None, secure=None, window_manager=None,
enable_push=False, ssl_context=None, proxy_host=None,
proxy_port=None, force_proto=None, **kwargs):
Expand Down
4 changes: 4 additions & 0 deletions hyper/http20/response.py
Expand Up @@ -11,6 +11,7 @@

from ..common.decoder import DeflateDecoder
from ..common.headers import HTTPHeaderMap
from ..common.util import HTTPVersion

log = logging.getLogger(__name__)

Expand All @@ -36,6 +37,9 @@ class HTTP20Response(object):
the persistent connections used in HTTP/2 this has no effect, and is done
soley for compatibility).
"""

version = HTTPVersion.http20

def __init__(self, headers, stream):
#: The reason phrase returned by the server. This is not used in
#: HTTP/2, and so is always the empty string.
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Expand Up @@ -96,6 +96,7 @@ def run_tests(self):
# module at lower than 1.0, because it doesn't support CFFI v1.0 yet.
':platform_python_implementation == "PyPy" and python_full_version < "2.7.9"': [
'cryptography<1.0'
]
],
':python_version == "2.7" or python_version == "3.3"': ['enum34>=1.0.4, <2']
}
)
13 changes: 13 additions & 0 deletions test/test_http11.py
Expand Up @@ -19,6 +19,7 @@
from hyper.http11.response import HTTP11Response
from hyper.common.headers import HTTPHeaderMap
from hyper.common.exceptions import ChunkedDecodeError, ConnectionResetError
from hyper.common.util import HTTPVersion
from hyper.compat import bytes, zlib_compressobj


Expand Down Expand Up @@ -838,6 +839,18 @@ def test_closing_chunked_reads_dont_call_close_callback(self):
assert r._sock is None
assert connection.close.call_count == 1

def test_connection_version(self):
c = HTTP11Connection('httpbin.org')
assert c.version is HTTPVersion.http11

def test_response_version(self):
d = DummySocket()
headers = {
b'transfer-encoding': [b'chunked'], b'connection': [b'close']
}
r = HTTP11Response(200, 'OK', headers, d)
assert r.version is HTTPVersion.http11


class DummySocket(object):
def __init__(self):
Expand Down
10 changes: 9 additions & 1 deletion test/test_hyper.py
Expand Up @@ -16,7 +16,7 @@
combine_repeated_headers, split_repeated_headers, h2_safe_headers
)
from hyper.common.headers import HTTPHeaderMap
from hyper.common.util import to_bytestring
from hyper.common.util import to_bytestring, HTTPVersion
from hyper.compat import zlib_compressobj, is_py2
from hyper.contrib import HTTP20Adapter
import hyper.http20.errors as errors
Expand Down Expand Up @@ -82,6 +82,10 @@ def test_connections_can_parse_ipv6_hosts_and_ports(self):
assert c.proxy_host == 'ffff:aaaa::1'
assert c.proxy_port == 8443

def test_connection_version(self):
c = HTTP20Connection('www.google.com')
assert c.version is HTTPVersion.http20

def test_ping(self, frame_buffer):
def data_callback(chunk, **kwargs):
frame_buffer.add_data(chunk)
Expand Down Expand Up @@ -1097,6 +1101,10 @@ def test_read_compressed_frames(self):

assert received == b'this is test data'

def test_response_version(self):
r = HTTP20Response(HTTPHeaderMap([(':status', '200')]), None)
assert r.version is HTTPVersion.http20


class TestHTTP20Adapter(object):
def test_adapter_reuses_connections(self):
Expand Down

0 comments on commit e76f185

Please sign in to comment.