diff --git a/httpx/config.py b/httpx/config.py index 6f26837ed9..3d2fe1c7d6 100644 --- a/httpx/config.py +++ b/httpx/config.py @@ -1,4 +1,3 @@ -import asyncio import ssl import typing from pathlib import Path @@ -65,16 +64,13 @@ def with_overrides( return self return SSLConfig(cert=cert, verify=verify) - async def load_ssl_context(self) -> ssl.SSLContext: + def load_ssl_context(self) -> ssl.SSLContext: if self.ssl_context is None: - if not self.verify: - self.ssl_context = self.load_ssl_context_no_verify() - else: - # Run the SSL loading in a threadpool, since it makes disk accesses. - loop = asyncio.get_event_loop() - self.ssl_context = await loop.run_in_executor( - None, self.load_ssl_context_verify - ) + self.ssl_context = ( + self.load_ssl_context_verify() + if self.verify + else self.load_ssl_context_no_verify() + ) assert self.ssl_context is not None return self.ssl_context diff --git a/httpx/dispatch/connection.py b/httpx/dispatch/connection.py index 4a303f2779..b51fec688b 100644 --- a/httpx/dispatch/connection.py +++ b/httpx/dispatch/connection.py @@ -66,7 +66,12 @@ async def connect( host = self.origin.host port = self.origin.port - ssl_context = await ssl.load_ssl_context() if self.origin.is_ssl else None + # Run the SSL loading in a threadpool, since it makes disk accesses. + ssl_context = ( + await self.backend.run_in_threadpool(ssl.load_ssl_context) + if self.origin.is_ssl + else None + ) if self.release_func is None: on_release = None diff --git a/tests/test_config.py b/tests/test_config.py index 33aebe7e03..b587e931a0 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -5,61 +5,54 @@ import httpx -@pytest.mark.asyncio -async def test_load_ssl_config(): +def test_load_ssl_config(): ssl_config = httpx.SSLConfig() - context = await ssl_config.load_ssl_context() + context = ssl_config.load_ssl_context() assert context.verify_mode == ssl.VerifyMode.CERT_REQUIRED assert context.check_hostname is True -@pytest.mark.asyncio -async def test_load_ssl_config_verify_non_existing_path(): +def test_load_ssl_config_verify_non_existing_path(): ssl_config = httpx.SSLConfig(verify="/path/to/nowhere") with pytest.raises(IOError): - await ssl_config.load_ssl_context() + ssl_config.load_ssl_context() -@pytest.mark.asyncio -async def test_load_ssl_config_verify_existing_file(): +def test_load_ssl_config_verify_existing_file(): ssl_config = httpx.SSLConfig(verify=httpx.config.DEFAULT_CA_BUNDLE_PATH) - context = await ssl_config.load_ssl_context() + context = ssl_config.load_ssl_context() assert context.verify_mode == ssl.VerifyMode.CERT_REQUIRED assert context.check_hostname is True -@pytest.mark.asyncio -async def test_load_ssl_config_verify_directory(): +def test_load_ssl_config_verify_directory(): path = httpx.config.DEFAULT_CA_BUNDLE_PATH.parent ssl_config = httpx.SSLConfig(verify=path) - context = await ssl_config.load_ssl_context() + context = ssl_config.load_ssl_context() assert context.verify_mode == ssl.VerifyMode.CERT_REQUIRED assert context.check_hostname is True -@pytest.mark.asyncio -async def test_load_ssl_config_cert_and_key(cert_pem_file, cert_private_key_file): +def test_load_ssl_config_cert_and_key(cert_pem_file, cert_private_key_file): ssl_config = httpx.SSLConfig(cert=(cert_pem_file, cert_private_key_file)) - context = await ssl_config.load_ssl_context() + context = ssl_config.load_ssl_context() assert context.verify_mode == ssl.VerifyMode.CERT_REQUIRED assert context.check_hostname is True -@pytest.mark.asyncio @pytest.mark.parametrize("password", [b"password", "password"]) -async def test_load_ssl_config_cert_and_encrypted_key( +def test_load_ssl_config_cert_and_encrypted_key( cert_pem_file, cert_encrypted_private_key_file, password ): ssl_config = httpx.SSLConfig( cert=(cert_pem_file, cert_encrypted_private_key_file, password) ) - context = await ssl_config.load_ssl_context() + context = ssl_config.load_ssl_context() assert context.verify_mode == ssl.VerifyMode.CERT_REQUIRED assert context.check_hostname is True -@pytest.mark.asyncio -async def test_load_ssl_config_cert_and_key_invalid_password( +def test_load_ssl_config_cert_and_key_invalid_password( cert_pem_file, cert_encrypted_private_key_file ): ssl_config = httpx.SSLConfig( @@ -67,20 +60,18 @@ async def test_load_ssl_config_cert_and_key_invalid_password( ) with pytest.raises(ssl.SSLError): - await ssl_config.load_ssl_context() + ssl_config.load_ssl_context() -@pytest.mark.asyncio -async def test_load_ssl_config_cert_without_key_raises(cert_pem_file): +def test_load_ssl_config_cert_without_key_raises(cert_pem_file): ssl_config = httpx.SSLConfig(cert=cert_pem_file) with pytest.raises(ssl.SSLError): - await ssl_config.load_ssl_context() + ssl_config.load_ssl_context() -@pytest.mark.asyncio -async def test_load_ssl_config_no_verify(): +def test_load_ssl_config_no_verify(): ssl_config = httpx.SSLConfig(verify=False) - context = await ssl_config.load_ssl_context() + context = ssl_config.load_ssl_context() assert context.verify_mode == ssl.VerifyMode.CERT_NONE assert context.check_hostname is False