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

Commit 4695044

Browse files
committed
Support external SSLContext
1 parent 392c2c2 commit 4695044

File tree

3 files changed

+57
-4
lines changed

3 files changed

+57
-4
lines changed

hyper/http20/connection.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@ class HTTP20Connection(object):
5151
:param enable_push: (optional) Whether the server is allowed to push
5252
resources to the client (see
5353
:meth:`get_pushes() <hyper.HTTP20Connection.get_pushes>`).
54+
:SSLContext: (optional) A class with custom certificate settings. If not provided
55+
then hyper's default SSLContext is used instead.
5456
"""
55-
def __init__(self, host, port=None, window_manager=None, enable_push=False,
57+
def __init__(self, host, port=None, window_manager=None, enable_push=False, SSLContext=None,
5658
**kwargs):
5759
"""
5860
Creates an HTTP/2 connection to a specific server.
@@ -67,6 +69,7 @@ def __init__(self, host, port=None, window_manager=None, enable_push=False,
6769
self.host, self.port = host, port
6870

6971
self._enable_push = enable_push
72+
self._SSLContext = SSLContext
7073

7174
#: The size of the in-memory buffer used to store data from the
7275
#: network. This is used as a performance optimisation. Increase buffer
@@ -206,7 +209,7 @@ def connect(self):
206209
if self._sock is None:
207210
sock = socket.create_connection((self.host, self.port), 5)
208211

209-
sock, proto = wrap_socket(sock, self.host)
212+
sock, proto = wrap_socket(sock, self.host, self._SSLContext)
210213
log.debug("Selected NPN protocol: %s", proto)
211214
assert proto in H2_NPN_PROTOCOLS
212215

hyper/tls.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@
2323
cert_loc = path.join(path.dirname(__file__), 'certs.pem')
2424

2525

26-
def wrap_socket(sock, server_hostname):
26+
def wrap_socket(sock, server_hostname, SSLContext=None):
2727
"""
2828
A vastly simplified SSL wrapping function. We'll probably extend this to
2929
do more things later.
3030
"""
3131
global _context
3232

3333
if _context is None: # pragma: no cover
34-
_context = _init_context()
34+
_context = SSLContext or _init_context()
3535

3636
# the spec requires SNI support
3737
ssl_sock = _context.wrap_socket(sock, server_hostname=server_hostname)

test/test_SSLContext.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Tests the hyper SSLContext.
4+
"""
5+
import hyper
6+
from hyper import HTTP20Connection
7+
import ssl
8+
import pytest
9+
10+
class TestSSLContext(object):
11+
"""
12+
Tests default and custom SSLContext
13+
"""
14+
def test_default_context(self):
15+
# Create default SSLContext
16+
hyper.tls._context = hyper.tls._init_context()
17+
assert hyper.tls._context.check_hostname == True
18+
assert hyper.tls._context.verify_mode == ssl.CERT_REQUIRED
19+
assert hyper.tls._context.options & ssl.OP_NO_COMPRESSION != 0
20+
21+
22+
def test_custom_context(self):
23+
# The following SSLContext doesn't provide any valid certicate.
24+
# Its purpose is only to confirm that hyper is not using its
25+
# default SSLContext.
26+
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
27+
context.verify_mode = ssl.CERT_NONE
28+
context.check_hostname = False
29+
30+
hyper.tls._context = context
31+
32+
assert hyper.tls._context.check_hostname == False
33+
assert hyper.tls._context.verify_mode == ssl.CERT_NONE
34+
assert hyper.tls._context.options & ssl.OP_NO_COMPRESSION == 0
35+
36+
37+
def test_http20Connection_with_custom_context(self):
38+
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
39+
context.set_default_verify_paths()
40+
context.load_verify_locations(cafile='hyper\certs.pem')
41+
context.verify_mode = ssl.CERT_REQUIRED
42+
context.check_hostname = True
43+
context.set_npn_protocols(['h2', 'h2-15'])
44+
context.options |= ssl.OP_NO_COMPRESSION
45+
46+
conn = HTTP20Connection('http2bin.org:443', SSLContext=context)
47+
48+
assert conn._SSLContext.check_hostname == True
49+
assert conn._SSLContext.verify_mode == ssl.CERT_REQUIRED
50+
assert conn._SSLContext.options & ssl.OP_NO_COMPRESSION != 0

0 commit comments

Comments
 (0)