Skip to content

Commit feff48d

Browse files
authored
Disable TLS in TLS warning for uvloop (#10726)
1 parent e0cc020 commit feff48d

File tree

5 files changed

+53
-1
lines changed

5 files changed

+53
-1
lines changed

CHANGES/7686.bugfix.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Disabled TLS in TLS warning (when using HTTPS proxies) for uvloop and newer Python versions -- by :user:`lezgomatt`.

CONTRIBUTORS.txt

+1
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ Martin Sucha
250250
Mathias Fröjdman
251251
Mathieu Dugré
252252
Matt VanEseltine
253+
Matthew Go
253254
Matthias Marquardt
254255
Matthieu Hauglustaine
255256
Matthieu Rigal

aiohttp/connector.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -1150,7 +1150,13 @@ def _warn_about_tls_in_tls(
11501150
if req.request_info.url.scheme != "https":
11511151
return
11521152

1153-
asyncio_supports_tls_in_tls = getattr(
1153+
# Check if uvloop is being used, which supports TLS in TLS,
1154+
# otherwise assume that asyncio's native transport is being used.
1155+
if type(underlying_transport).__module__.startswith("uvloop"):
1156+
return
1157+
1158+
# Support in asyncio was added in Python 3.11 (bpo-44011)
1159+
asyncio_supports_tls_in_tls = sys.version_info >= (3, 11) or getattr(
11541160
underlying_transport,
11551161
"_start_tls_compatible",
11561162
False,

tests/conftest.py

+17
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@
3232
except ImportError:
3333
TRUSTME = False
3434

35+
36+
try:
37+
import uvloop
38+
except ImportError:
39+
uvloop = None # type: ignore[assignment]
40+
41+
3542
pytest_plugins = ("aiohttp.pytest_plugin", "pytester")
3643

3744
IS_HPUX = sys.platform.startswith("hp-ux")
@@ -234,6 +241,16 @@ def selector_loop() -> Iterator[asyncio.AbstractEventLoop]:
234241
yield _loop
235242

236243

244+
@pytest.fixture
245+
def uvloop_loop() -> Iterator[asyncio.AbstractEventLoop]:
246+
policy = uvloop.EventLoopPolicy()
247+
asyncio.set_event_loop_policy(policy)
248+
249+
with loop_context(policy.new_event_loop) as _loop:
250+
asyncio.set_event_loop(_loop)
251+
yield _loop
252+
253+
237254
@pytest.fixture
238255
def netrc_contents(
239256
tmp_path: Path,

tests/test_proxy_functional.py

+27
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import asyncio
22
import os
33
import pathlib
4+
import platform
45
import ssl
56
import sys
67
from re import match as match_regex
@@ -240,6 +241,32 @@ async def test_https_proxy_unsupported_tls_in_tls(
240241
await asyncio.sleep(0.1)
241242

242243

244+
@pytest.mark.usefixtures("uvloop_loop")
245+
@pytest.mark.skipif(
246+
platform.system() == "Windows" or sys.implementation.name != "cpython",
247+
reason="uvloop is not supported on Windows and non-CPython implementations",
248+
)
249+
@pytest.mark.filterwarnings(r"ignore:.*ssl.OP_NO_SSL*")
250+
# Filter out the warning from
251+
# https://github.com/abhinavsingh/proxy.py/blob/30574fd0414005dfa8792a6e797023e862bdcf43/proxy/common/utils.py#L226
252+
# otherwise this test will fail because the proxy will die with an error.
253+
async def test_uvloop_secure_https_proxy(
254+
client_ssl_ctx: ssl.SSLContext,
255+
secure_proxy_url: URL,
256+
) -> None:
257+
"""Ensure HTTPS sites are accessible through a secure proxy without warning when using uvloop."""
258+
conn = aiohttp.TCPConnector()
259+
sess = aiohttp.ClientSession(connector=conn)
260+
url = URL("https://example.com")
261+
262+
async with sess.get(url, proxy=secure_proxy_url, ssl=client_ssl_ctx) as response:
263+
assert response.status == 200
264+
265+
await sess.close()
266+
await conn.close()
267+
await asyncio.sleep(0.1)
268+
269+
243270
@pytest.fixture
244271
def proxy_test_server(
245272
aiohttp_raw_server: AiohttpRawServer,

0 commit comments

Comments
 (0)