Skip to content
This repository was archived by the owner on Apr 14, 2022. It is now read-only.

Commit 2c915e3

Browse files
Merge pull request #132 from pquentin/merge-from-master-2019-10-05
Merge from master (October 5th, 2019)
2 parents 290c553 + 823b101 commit 2c915e3

12 files changed

+151
-171
lines changed

_travis/install.sh

-3
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@ if [[ "$(uname -s)" == 'Darwin' ]]; then
2929

3030
install_mac_python $MACPYTHON
3131

32-
# Enable TLS 1.3 on macOS
33-
sudo defaults write /Library/Preferences/com.apple.networkd tcp_connect_enable_tls13 1
34-
3532
# Install Nox
3633
python3 -m pip install nox
3734

src/urllib3/contrib/_securetransport/bindings.py

+1
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ class SecurityConst(object):
415415
kTLSProtocol1 = 4
416416
kTLSProtocol11 = 7
417417
kTLSProtocol12 = 8
418+
# SecureTransport does not support TLS 1.3 even if there's a constant for it
418419
kTLSProtocol13 = 10
419420
kTLSProtocolMaxSupported = 999
420421

src/urllib3/contrib/securetransport.py

+4-15
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,10 @@
144144
]
145145

146146
# Basically this is simple: for PROTOCOL_SSLv23 we turn it into a low of
147-
# TLSv1 and a high of TLSv1.3. For everything else, we pin to that version.
148-
# TLSv1 to 1.2 are supported on macOS 10.8+ and TLSv1.3 is macOS 10.13+
147+
# TLSv1 and a high of TLSv1.2. For everything else, we pin to that version.
148+
# TLSv1 to 1.2 are supported on macOS 10.8+
149149
_protocol_to_min_max = {
150-
util.PROTOCOL_TLS: (
151-
SecurityConst.kTLSProtocol1,
152-
SecurityConst.kTLSProtocolMaxSupported,
153-
)
150+
util.PROTOCOL_TLS: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12)
154151
}
155152

156153
if hasattr(ssl, "PROTOCOL_SSLv2"):
@@ -488,15 +485,7 @@ def handshake(
488485
result = Security.SSLSetProtocolVersionMin(self.context, min_version)
489486
_assert_no_error(result)
490487

491-
# TLS 1.3 isn't necessarily enabled by the OS
492-
# so we have to detect when we error out and try
493-
# setting TLS 1.3 if it's allowed. kTLSProtocolMaxSupported
494-
# was added in macOS 10.13 along with kTLSProtocol13.
495488
result = Security.SSLSetProtocolVersionMax(self.context, max_version)
496-
if result != 0 and max_version == SecurityConst.kTLSProtocolMaxSupported:
497-
result = Security.SSLSetProtocolVersionMax(
498-
self.context, SecurityConst.kTLSProtocol12
499-
)
500489
_assert_no_error(result)
501490

502491
# If there's a trust DB, we need to use it. We do that by telling
@@ -707,7 +696,7 @@ def version(self):
707696
)
708697
_assert_no_error(result)
709698
if protocol.value == SecurityConst.kTLSProtocol13:
710-
return "TLSv1.3"
699+
raise ssl.SSLError("SecureTransport does not support TLS 1.3")
711700
elif protocol.value == SecurityConst.kTLSProtocol12:
712701
return "TLSv1.2"
713702
elif protocol.value == SecurityConst.kTLSProtocol11:

test/contrib/test_securetransport.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,8 @@ def teardown_module():
3131
pass
3232

3333

34-
# Currently TLSv1.3 doesn't work with SecureTransport despite
35-
# Apple previously documenting support. See:
36-
# https://github.com/python-trio/trio/issues/1165#issuecomment-526563135
34+
# SecureTransport does not support TLSv1.3
35+
# https://github.com/urllib3/urllib3/issues/1674
3736
from ..with_dummyserver.test_https import ( # noqa: F401
3837
TestHTTPS,
3938
TestHTTPS_TLSv1,

test/test_connectionpool.py

-1
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,6 @@ def __call__(self, *args, **kwargs):
450450

451451
def _test(exception, *args):
452452
with HTTPConnectionPool(host="localhost", maxsize=1, block=True) as pool:
453-
454453
# Verify that the request succeeds after two attempts, and that the
455454
# connection is left on the response object, instead of being
456455
# released back into the pool.

test/test_no_ssl.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,14 @@ def pop(self):
6565

6666
class TestWithoutSSL(object):
6767
@classmethod
68-
def setup_class(self):
68+
def setup_class(cls):
6969
sys.modules.pop("ssl", None)
7070
sys.modules.pop("_ssl", None)
7171

7272
module_stash.stash()
7373
sys.meta_path.insert(0, ssl_blocker)
7474

75-
def teardown_class(self):
75+
def teardown_class(cls):
7676
sys.meta_path.remove(ssl_blocker)
7777
module_stash.pop()
7878

test/test_proxymanager.py

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ class TestProxyManager(object):
77
def test_proxy_headers(self):
88
url = "http://pypi.org/project/urllib3/"
99
with ProxyManager("http://something:1234") as p:
10-
1110
# Verify default headers
1211
default_headers = {"Accept": "*/*", "Host": "pypi.org"}
1312
headers = p._set_proxy_headers(url)

test/with_dummyserver/test_connectionpool.py

+72-73
Original file line numberDiff line numberDiff line change
@@ -319,29 +319,29 @@ def test_socket_options(self):
319319
"""Test that connections accept socket options."""
320320
# This test needs to be here in order to be run. socket.create_connection actually tries to
321321
# connect to the host provided so we need a dummyserver to be running.
322-
pool = HTTPConnectionPool(
322+
with HTTPConnectionPool(
323323
self.host,
324324
self.port,
325325
socket_options=[(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)],
326-
)
327-
conn = pool._new_conn()
328-
conn.connect()
329-
s = conn._sock
330-
using_keepalive = s.getsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE) > 0
331-
assert using_keepalive
332-
s.close()
326+
) as pool:
327+
conn = pool._new_conn()
328+
conn.connect()
329+
s = conn._sock
330+
using_keepalive = s.getsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE) > 0
331+
assert using_keepalive
332+
s.close()
333333

334334
def test_disable_default_socket_options(self):
335335
"""Test that passing None disables all socket options."""
336336
# This test needs to be here in order to be run. socket.create_connection actually tries
337337
# to connect to the host provided so we need a dummyserver to be running.
338-
pool = HTTPConnectionPool(self.host, self.port, socket_options=None)
339-
conn = pool._new_conn()
340-
conn.connect()
341-
s = conn._sock
342-
using_nagle = s.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY) == 0
343-
assert using_nagle
344-
s.close()
338+
with HTTPConnectionPool(self.host, self.port, socket_options=None) as pool:
339+
conn = pool._new_conn()
340+
conn.connect()
341+
s = conn._sock
342+
using_nagle = s.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY) == 0
343+
assert using_nagle
344+
s.close()
345345

346346
def test_defaults_are_applied(self):
347347
"""Test that modifying the default socket options works."""
@@ -372,12 +372,12 @@ def test_defaults_are_applied(self):
372372
def test_connection_error_retries(self):
373373
""" ECONNREFUSED error should raise a connection error, with retries """
374374
port = find_unused_port()
375-
pool = HTTPConnectionPool(self.host, port)
376-
try:
377-
pool.request("GET", "/", retries=Retry(connect=3))
378-
self.fail("Should have failed with a connection error.")
379-
except MaxRetryError as e:
380-
assert type(e.reason) == NewConnectionError
375+
with HTTPConnectionPool(self.host, port) as pool:
376+
try:
377+
pool.request("GET", "/", retries=Retry(connect=3))
378+
self.fail("Should have failed with a connection error.")
379+
except MaxRetryError as e:
380+
assert type(e.reason) == NewConnectionError
381381

382382
def test_timeout_success(self):
383383
timeout = Timeout(connect=3, read=5, total=None)
@@ -395,12 +395,12 @@ def test_timeout_success(self):
395395
pool.request("GET", "/")
396396

397397
def test_bad_connect(self):
398-
pool = HTTPConnectionPool("badhost.invalid", self.port)
399-
try:
400-
pool.request("GET", "/", retries=5)
401-
self.fail("should raise timeout exception here")
402-
except MaxRetryError as e:
403-
assert type(e.reason) == NewConnectionError
398+
with HTTPConnectionPool("badhost.invalid", self.port) as pool:
399+
try:
400+
pool.request("GET", "/", retries=5)
401+
self.fail("should raise timeout exception here")
402+
except MaxRetryError as e:
403+
assert type(e.reason) == NewConnectionError
404404

405405
def test_keepalive(self):
406406
with HTTPConnectionPool(self.host, self.port, block=True, maxsize=1) as pool:
@@ -567,59 +567,58 @@ def test_lazy_load_twice(self):
567567
# This test is sad and confusing. Need to figure out what's
568568
# going on with partial reads and socket reuse.
569569

570-
pool = HTTPConnectionPool(
570+
with HTTPConnectionPool(
571571
self.host, self.port, block=True, maxsize=1, timeout=2
572-
)
573-
574-
payload_size = 1024 * 2
575-
first_chunk = 512
572+
) as pool:
573+
payload_size = 1024 * 2
574+
first_chunk = 512
576575

577-
boundary = "foo"
576+
boundary = "foo"
578577

579-
req_data = {"count": "a" * payload_size}
580-
resp_data = encode_multipart_formdata(req_data, boundary=boundary)[0]
578+
req_data = {"count": "a" * payload_size}
579+
resp_data = encode_multipart_formdata(req_data, boundary=boundary)[0]
581580

582-
req2_data = {"count": "b" * payload_size}
583-
resp2_data = encode_multipart_formdata(req2_data, boundary=boundary)[0]
581+
req2_data = {"count": "b" * payload_size}
582+
resp2_data = encode_multipart_formdata(req2_data, boundary=boundary)[0]
584583

585-
r1 = pool.request(
586-
"POST",
587-
"/echo",
588-
fields=req_data,
589-
multipart_boundary=boundary,
590-
preload_content=False,
591-
)
592-
593-
first_data = r1.read(first_chunk)
594-
assert len(first_data) > 0
595-
assert first_data == resp_data[: len(first_data)]
596-
597-
try:
598-
r2 = pool.request(
584+
r1 = pool.request(
599585
"POST",
600586
"/echo",
601-
fields=req2_data,
587+
fields=req_data,
602588
multipart_boundary=boundary,
603589
preload_content=False,
604-
pool_timeout=0.001,
605590
)
606591

607-
# This branch should generally bail here, but maybe someday it will
608-
# work? Perhaps by some sort of magic. Consider it a TODO.
592+
first_data = r1.read(first_chunk)
593+
assert len(first_data) > 0
594+
assert first_data == resp_data[: len(first_data)]
595+
596+
try:
597+
r2 = pool.request(
598+
"POST",
599+
"/echo",
600+
fields=req2_data,
601+
multipart_boundary=boundary,
602+
preload_content=False,
603+
pool_timeout=0.001,
604+
)
609605

610-
second_data = r2.read(first_chunk)
611-
assert len(second_data) > 0
612-
assert second_data == resp2_data[: len(second_data)]
606+
# This branch should generally bail here, but maybe someday it will
607+
# work? Perhaps by some sort of magic. Consider it a TODO.
613608

614-
assert r1.read() == resp_data[len(first_data) :]
615-
assert r2.read() == resp2_data[len(second_data) :]
616-
assert pool.num_requests == 2
609+
second_data = r2.read(first_chunk)
610+
assert len(second_data) > 0
611+
assert second_data == resp2_data[: len(second_data)]
617612

618-
except EmptyPoolError:
619-
assert r1.read() == resp_data[len(first_data) :]
620-
assert pool.num_requests == 1
613+
assert r1.read() == resp_data[len(first_data) :]
614+
assert r2.read() == resp2_data[len(second_data) :]
615+
assert pool.num_requests == 2
621616

622-
assert pool.num_connections == 1
617+
except EmptyPoolError:
618+
assert r1.read() == resp_data[len(first_data) :]
619+
assert pool.num_requests == 1
620+
621+
assert pool.num_connections == 1
623622

624623
def test_for_double_release(self):
625624
MAXSIZE = 5
@@ -653,11 +652,11 @@ def test_for_double_release(self):
653652

654653
def test_connections_arent_released(self):
655654
MAXSIZE = 5
656-
pool = HTTPConnectionPool(self.host, self.port, maxsize=MAXSIZE)
657-
assert pool.pool.qsize() == MAXSIZE
655+
with HTTPConnectionPool(self.host, self.port, maxsize=MAXSIZE) as pool:
656+
assert pool.pool.qsize() == MAXSIZE
658657

659-
pool.request("GET", "/", preload_content=False)
660-
assert pool.pool.qsize() == MAXSIZE - 1
658+
pool.request("GET", "/", preload_content=False)
659+
assert pool.pool.qsize() == MAXSIZE - 1
661660

662661
def test_dns_error(self):
663662
pool = HTTPConnectionPool(
@@ -684,11 +683,11 @@ def test_source_address(self):
684683

685684
def test_source_address_error(self):
686685
for addr in INVALID_SOURCE_ADDRESSES:
687-
pool = HTTPConnectionPool(
686+
with HTTPConnectionPool(
688687
self.host, self.port, source_address=addr, retries=False
689-
)
690-
with pytest.raises(NewConnectionError):
691-
pool.request("GET", "/source_address?{0}".format(addr))
688+
) as pool:
689+
with pytest.raises(NewConnectionError):
690+
pool.request("GET", "/source_address?{0}".format(addr))
692691

693692
def test_stream_keepalive(self):
694693
x = 2

0 commit comments

Comments
 (0)