Skip to content

Commit 9a40d12

Browse files
authored
Avoid reloading root certificates to improve concurrent performance (#6667)
1 parent 0c030f7 commit 9a40d12

File tree

1 file changed

+28
-18
lines changed

1 file changed

+28
-18
lines changed

src/requests/adapters.py

+28-18
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from urllib3.util import Timeout as TimeoutSauce
2727
from urllib3.util import parse_url
2828
from urllib3.util.retry import Retry
29+
from urllib3.util.ssl_ import create_urllib3_context
2930

3031
from .auth import _basic_auth_str
3132
from .compat import basestring, urlparse
@@ -71,6 +72,11 @@ def SOCKSProxyManager(*args, **kwargs):
7172
DEFAULT_RETRIES = 0
7273
DEFAULT_POOL_TIMEOUT = None
7374

75+
_preloaded_ssl_context = create_urllib3_context()
76+
_preloaded_ssl_context.load_verify_locations(
77+
extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH)
78+
)
79+
7480

7581
def _urllib3_request_context(
7682
request: "PreparedRequest",
@@ -85,8 +91,13 @@ def _urllib3_request_context(
8591
cert_reqs = "CERT_REQUIRED"
8692
if verify is False:
8793
cert_reqs = "CERT_NONE"
88-
if isinstance(verify, str):
89-
pool_kwargs["ca_certs"] = verify
94+
elif verify is True:
95+
pool_kwargs["ssl_context"] = _preloaded_ssl_context
96+
elif isinstance(verify, str):
97+
if not os.path.isdir(verify):
98+
pool_kwargs["ca_certs"] = verify
99+
else:
100+
pool_kwargs["ca_cert_dir"] = verify
90101
pool_kwargs["cert_reqs"] = cert_reqs
91102
if client_cert is not None:
92103
if isinstance(client_cert, tuple) and len(client_cert) == 2:
@@ -284,27 +295,26 @@ def cert_verify(self, conn, url, verify, cert):
284295
:param cert: The SSL certificate to verify.
285296
"""
286297
if url.lower().startswith("https") and verify:
287-
cert_loc = None
298+
conn.cert_reqs = "CERT_REQUIRED"
288299

289-
# Allow self-specified cert location.
300+
# Only load the CA certificates if 'verify' is a string indicating the CA bundle to use.
301+
# Otherwise, if verify is a boolean, we don't load anything since
302+
# the connection will be using a context with the default certificates already loaded,
303+
# and this avoids a call to the slow load_verify_locations()
290304
if verify is not True:
305+
# `verify` must be a str with a path then
291306
cert_loc = verify
292307

293-
if not cert_loc:
294-
cert_loc = extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH)
295-
296-
if not cert_loc or not os.path.exists(cert_loc):
297-
raise OSError(
298-
f"Could not find a suitable TLS CA certificate bundle, "
299-
f"invalid path: {cert_loc}"
300-
)
308+
if not os.path.exists(cert_loc):
309+
raise OSError(
310+
f"Could not find a suitable TLS CA certificate bundle, "
311+
f"invalid path: {cert_loc}"
312+
)
301313

302-
conn.cert_reqs = "CERT_REQUIRED"
303-
304-
if not os.path.isdir(cert_loc):
305-
conn.ca_certs = cert_loc
306-
else:
307-
conn.ca_cert_dir = cert_loc
314+
if not os.path.isdir(cert_loc):
315+
conn.ca_certs = cert_loc
316+
else:
317+
conn.ca_cert_dir = cert_loc
308318
else:
309319
conn.cert_reqs = "CERT_NONE"
310320
conn.ca_certs = None

0 commit comments

Comments
 (0)