-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
test_connection.py
100 lines (86 loc) · 3.66 KB
/
test_connection.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import datetime
import mock
import pytest
from urllib3.connection import (
CertificateError,
_match_hostname,
RECENT_DATE,
SSLSessionResumptionPolicy,
HTTPSConnection,
)
class TestConnection(object):
"""
Tests in this suite should not make any network requests or connections.
"""
@mock.patch('urllib3.connection.HTTPSConnection.connect', return_value=None)
def test_httpsconn_save_ssl_session_if_policy_balanced(self, mock_connect):
"""
This is an edge-case which may not be covered in test_https, because the
``session.has_ticket`` should really never be ``True`` pre-TLSv1.3,
since we set OP_NO_TICKET, which means the server should not be sending a ticket.
Just in case, this code path should be checked too for 100% coverage.
"""
# __init__ will not call connect(), so no socket connection
# is established in this test:
https_conn = HTTPSConnection(
"localhost",
ssl_session_resumption_policy=SSLSessionResumptionPolicy.BALANCED,
)
sock = mock.Mock()
session = mock.Mock()
sock.session = session
https_conn.sock = sock
attr_not_set = object()
for ver in (attr_not_set, None, "TLSv1", "TLSv1.1", "TLSv1.2"):
if ver is not attr_not_set:
sock.version = lambda: ver
for has_ticket in (True, False):
https_conn.ssl_session = None
session.has_ticket = has_ticket
https_conn._save_ssl_session_if_needed()
assert (
not has_ticket or https_conn.ssl_session is None
), "For TLS version %s has_ticket: %s" % (ver, has_ticket)
# finally check that in case of TLSv1.3, it's saved:
sock.version = lambda: "TLSv1.3"
for has_ticket in (True, False):
https_conn.ssl_session = None
session.has_ticket = has_ticket
https_conn._save_ssl_session_if_needed()
assert https_conn.ssl_session is session
mock_connect.assert_not_called()
def test_match_hostname_no_cert(self):
cert = None
asserted_hostname = "foo"
with pytest.raises(ValueError):
_match_hostname(cert, asserted_hostname)
def test_match_hostname_empty_cert(self):
cert = {}
asserted_hostname = "foo"
with pytest.raises(ValueError):
_match_hostname(cert, asserted_hostname)
def test_match_hostname_match(self):
cert = {"subjectAltName": [("DNS", "foo")]}
asserted_hostname = "foo"
_match_hostname(cert, asserted_hostname)
def test_match_hostname_mismatch(self):
cert = {"subjectAltName": [("DNS", "foo")]}
asserted_hostname = "bar"
try:
with mock.patch("urllib3.connection.log.warning") as mock_log:
_match_hostname(cert, asserted_hostname)
except CertificateError as e:
assert "hostname 'bar' doesn't match 'foo'" in str(e)
mock_log.assert_called_once_with(
"Certificate did not match expected hostname: %s. Certificate: %s",
"bar",
{"subjectAltName": [("DNS", "foo")]},
)
assert e._peer_cert == cert
def test_recent_date(self):
# This test is to make sure that the RECENT_DATE value
# doesn't get too far behind what the current date is.
# When this test fails update urllib3.connection.RECENT_DATE
# according to the rules defined in that file.
two_years = datetime.timedelta(days=365 * 2)
assert RECENT_DATE > (datetime.datetime.today() - two_years).date()