Skip to content

Commit d32d580

Browse files
authored
[PR #9301/c240b52 backport][3.10] Replace code that can now be handled by yarl (#9314)
1 parent fd5ece6 commit d32d580

File tree

4 files changed

+49
-23
lines changed

4 files changed

+49
-23
lines changed

CHANGES/9301.misc.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Replaced code that can now be handled by ``yarl`` -- by :user:`bdraco`.

aiohttp/client_reqrep.py

+21-11
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
import attr
2929
from multidict import CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy
30-
from yarl import URL
30+
from yarl import URL, __version__ as yarl_version
3131

3232
from . import hdrs, helpers, http, multipart, payload
3333
from .abc import AbstractStreamWriter
@@ -90,6 +90,10 @@
9090

9191
_CONTAINS_CONTROL_CHAR_RE = re.compile(r"[^-!#$%&'*+.^_`|~0-9a-zA-Z]")
9292
json_re = re.compile(r"^application/(?:[\w.+-]+?\+)?json")
93+
_YARL_SUPPORTS_HOST_SUBCOMPONENT = tuple(map(int, yarl_version.split(".")[:2])) >= (
94+
1,
95+
13,
96+
)
9397

9498

9599
def _gen_default_accept_encoding() -> str:
@@ -429,9 +433,13 @@ def update_headers(self, headers: Optional[LooseHeaders]) -> None:
429433
self.headers: CIMultiDict[str] = CIMultiDict()
430434

431435
# add host
432-
netloc = cast(str, self.url.raw_host)
433-
if helpers.is_ipv6_address(netloc):
434-
netloc = f"[{netloc}]"
436+
if _YARL_SUPPORTS_HOST_SUBCOMPONENT:
437+
netloc = self.url.host_subcomponent
438+
assert netloc is not None
439+
else:
440+
netloc = cast(str, self.url.raw_host)
441+
if helpers.is_ipv6_address(netloc):
442+
netloc = f"[{netloc}]"
435443
# See https://github.com/aio-libs/aiohttp/issues/3636.
436444
netloc = netloc.rstrip(".")
437445
if self.url.port is not None and not self.url.is_default_port():
@@ -676,17 +684,19 @@ async def send(self, conn: "Connection") -> "ClientResponse":
676684
# - not CONNECT proxy must send absolute form URI
677685
# - most common is origin form URI
678686
if self.method == hdrs.METH_CONNECT:
679-
connect_host = self.url.raw_host
680-
assert connect_host is not None
681-
if helpers.is_ipv6_address(connect_host):
682-
connect_host = f"[{connect_host}]"
687+
if _YARL_SUPPORTS_HOST_SUBCOMPONENT:
688+
connect_host = self.url.host_subcomponent
689+
assert connect_host is not None
690+
else:
691+
connect_host = self.url.raw_host
692+
assert connect_host is not None
693+
if helpers.is_ipv6_address(connect_host):
694+
connect_host = f"[{connect_host}]"
683695
path = f"{connect_host}:{self.url.port}"
684696
elif self.proxy and not self.is_ssl():
685697
path = str(self.url)
686698
else:
687-
path = self.url.raw_path
688-
if self.url.raw_query_string:
689-
path += "?" + self.url.raw_query_string
699+
path = self.url.raw_path_qs
690700

691701
protocol = conn.protocol
692702
assert protocol is not None

tests/test_client_request.py

+11-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from yarl import URL
1515

1616
import aiohttp
17-
from aiohttp import BaseConnector, hdrs, helpers, payload
17+
from aiohttp import BaseConnector, client_reqrep, hdrs, helpers, payload
1818
from aiohttp.client_exceptions import ClientConnectionError
1919
from aiohttp.client_reqrep import (
2020
ClientRequest,
@@ -280,9 +280,16 @@ def test_host_header_ipv4(make_request) -> None:
280280
assert req.headers["HOST"] == "127.0.0.2"
281281

282282

283-
def test_host_header_ipv6(make_request) -> None:
284-
req = make_request("get", "http://[::2]")
285-
assert req.headers["HOST"] == "[::2]"
283+
@pytest.mark.parametrize("yarl_supports_host_subcomponent", [True, False])
284+
def test_host_header_ipv6(make_request, yarl_supports_host_subcomponent: bool) -> None:
285+
# Ensure the old path is tested for old yarl versions
286+
with mock.patch.object(
287+
client_reqrep,
288+
"_YARL_SUPPORTS_HOST_SUBCOMPONENT",
289+
yarl_supports_host_subcomponent,
290+
):
291+
req = make_request("get", "http://[::2]")
292+
assert req.headers["HOST"] == "[::2]"
286293

287294

288295
def test_host_header_ipv4_with_port(make_request) -> None:

tests/test_proxy_functional.py

+16-8
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from yarl import URL
1313

1414
import aiohttp
15-
from aiohttp import web
15+
from aiohttp import client_reqrep, web
1616
from aiohttp.client_exceptions import ClientConnectionError
1717
from aiohttp.helpers import IS_MACOS, IS_WINDOWS
1818

@@ -95,6 +95,7 @@ async def handler(*args, **kwargs):
9595
reason="asyncio on this python does not support TLS in TLS",
9696
)
9797
@pytest.mark.parametrize("web_server_endpoint_type", ("http", "https"))
98+
@pytest.mark.parametrize("yarl_supports_host_subcomponent", [True, False])
9899
@pytest.mark.filterwarnings(r"ignore:.*ssl.OP_NO_SSL*")
99100
# Filter out the warning from
100101
# https://github.com/abhinavsingh/proxy.py/blob/30574fd0414005dfa8792a6e797023e862bdcf43/proxy/common/utils.py#L226
@@ -104,18 +105,25 @@ async def test_secure_https_proxy_absolute_path(
104105
secure_proxy_url: URL,
105106
web_server_endpoint_url: str,
106107
web_server_endpoint_payload: str,
108+
yarl_supports_host_subcomponent: bool,
107109
) -> None:
108110
"""Ensure HTTP(S) sites are accessible through a secure proxy."""
109111
conn = aiohttp.TCPConnector()
110112
sess = aiohttp.ClientSession(connector=conn)
111113

112-
async with sess.get(
113-
web_server_endpoint_url,
114-
proxy=secure_proxy_url,
115-
ssl=client_ssl_ctx, # used for both proxy and endpoint connections
116-
) as response:
117-
assert response.status == 200
118-
assert await response.text() == web_server_endpoint_payload
114+
# Ensure the old path is tested for old yarl versions
115+
with mock.patch.object(
116+
client_reqrep,
117+
"_YARL_SUPPORTS_HOST_SUBCOMPONENT",
118+
yarl_supports_host_subcomponent,
119+
):
120+
async with sess.get(
121+
web_server_endpoint_url,
122+
proxy=secure_proxy_url,
123+
ssl=client_ssl_ctx, # used for both proxy and endpoint connections
124+
) as response:
125+
assert response.status == 200
126+
assert await response.text() == web_server_endpoint_payload
119127

120128
await sess.close()
121129
await conn.close()

0 commit comments

Comments
 (0)