diff --git a/httpie/compat.py b/httpie/compat.py index fcf167ca7d..d12abcff02 100644 --- a/httpie/compat.py +++ b/httpie/compat.py @@ -1,8 +1,9 @@ import sys +from ssl import SSLContext from typing import Any, Optional, Iterable from httpie.cookies import HTTPieCookiePolicy -from http import cookiejar # noqa +from http import cookiejar # noqa # Request does not carry the original policy attached to the @@ -10,7 +11,6 @@ # policy. cookiejar.DefaultCookiePolicy = HTTPieCookiePolicy - is_windows = 'win32' in str(sys.platform).lower() is_frozen = getattr(sys, 'frozen', False) @@ -66,7 +66,6 @@ def __get__(self, instance, cls=None): res = instance.__dict__[self.name] = self.func(instance) return res - # importlib_metadata was a provisional module, so the APIs changed quite a few times # between 3.8-3.10. It was also not included in the standard library until 3.8, so # we install the backport for <3.8. @@ -100,3 +99,15 @@ def get_dist_name(entry_point: importlib_metadata.EntryPoint) -> Optional[str]: return None else: return metadata.get('name') + + +def ensure_default_certs_loaded(ssl_context: SSLContext) -> None: + """ + Workaround for a bug in Requests 2.32.3 + + See + + """ + if hasattr(ssl_context, 'load_default_certs'): + if not ssl_context.get_ca_certs(): + ssl_context.load_default_certs() diff --git a/httpie/ssl_.py b/httpie/ssl_.py index 6df4ff45c4..6b3ef38cf6 100644 --- a/httpie/ssl_.py +++ b/httpie/ssl_.py @@ -1,13 +1,15 @@ import ssl from typing import NamedTuple, Optional -from httpie.adapters import HTTPAdapter # noinspection PyPackageRequirements from urllib3.util.ssl_ import ( create_urllib3_context, resolve_ssl_version, ) +from .adapters import HTTPAdapter +from .compat import ensure_default_certs_loaded + SSL_VERSION_ARG_MAPPING = { 'ssl2.3': 'PROTOCOL_SSLv23', @@ -71,7 +73,7 @@ def _create_ssl_context( ssl_version: str = None, ciphers: str = None, ) -> 'ssl.SSLContext': - context = create_urllib3_context( + ssl_context = create_urllib3_context( ciphers=ciphers, ssl_version=resolve_ssl_version(ssl_version), # Since we are using a custom SSL context, we need to pass this @@ -79,11 +81,8 @@ def _create_ssl_context( # in `super().cert_verify()`. cert_reqs=ssl.CERT_REQUIRED if verify else ssl.CERT_NONE ) - if not context.get_ca_certs(): - # Workaround for a bug in requests 2.32.3 - # See - context.load_default_certs() - return context + ensure_default_certs_loaded(ssl_context) + return ssl_context @classmethod def get_default_ciphers_names(cls):