]> git.ipfire.org Git - thirdparty/httpx.git/commitdiff
Run SSLConfig cert loading in threadpool (#209)
authorCan Sarıgöl <cansarigol@derinbilgi.com.tr>
Thu, 15 Aug 2019 02:30:01 +0000 (05:30 +0300)
committerSeth Michael Larson <sethmichaellarson@gmail.com>
Thu, 15 Aug 2019 02:30:01 +0000 (21:30 -0500)
httpx/config.py
httpx/dispatch/connection.py
tests/test_config.py

index 6f26837ed9964b042f6843a0d1ebaa1c17117ec1..3d2fe1c7d6f8ea8e4a5fc9171c3a59751f51a792 100644 (file)
@@ -1,4 +1,3 @@
-import asyncio
 import ssl
 import typing
 from pathlib import Path
@@ -65,16 +64,13 @@ class SSLConfig:
             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
index 4a303f27793b7197dc4fa25ba942c890140a108e..b51fec688b57ab78133d595d3c5f350706b65b08 100644 (file)
@@ -66,7 +66,12 @@ class HTTPConnection(AsyncDispatcher):
 
         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
index 33aebe7e030cfa5ab662f2d9545a4a00cce3b367..b587e931a0c1cfb923b5bcc4efe190a1b177f2cd 100644 (file)
@@ -5,61 +5,54 @@ import pytest
 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