Skip to content

Commit 8e395a1

Browse files
authored
[PR #9366/43deadb2 backport][3.10] Small speed up to update_headers (#9383)
1 parent 57ce46c commit 8e395a1

File tree

1 file changed

+41
-22
lines changed

1 file changed

+41
-22
lines changed

aiohttp/client_reqrep.py

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -431,30 +431,49 @@ def update_headers(self, headers: Optional[LooseHeaders]) -> None:
431431
"""Update request headers."""
432432
self.headers: CIMultiDict[str] = CIMultiDict()
433433

434-
# add host
434+
# Build the host header
435435
if _YARL_SUPPORTS_HOST_SUBCOMPONENT:
436-
netloc = self.url.host_subcomponent
437-
assert netloc is not None
436+
host = self.url.host_subcomponent
437+
# host_subcomponent is None when the URL is a relative URL.
438+
# but we know we do not have a relative URL here.
439+
assert host is not None
438440
else:
439-
netloc = cast(str, self.url.raw_host)
440-
if helpers.is_ipv6_address(netloc):
441-
netloc = f"[{netloc}]"
442-
# See https://github.com/aio-libs/aiohttp/issues/3636.
443-
netloc = netloc.rstrip(".")
444-
if self.url.port is not None and not self.url.is_default_port():
445-
netloc += ":" + str(self.url.port)
446-
self.headers[hdrs.HOST] = netloc
447-
448-
if headers:
449-
if isinstance(headers, (dict, MultiDictProxy, MultiDict)):
450-
headers = headers.items()
451-
452-
for key, value in headers: # type: ignore[misc]
453-
# A special case for Host header
454-
if key.lower() == "host":
455-
self.headers[key] = value
456-
else:
457-
self.headers.add(key, value)
441+
host = cast(str, self.url.raw_host)
442+
if helpers.is_ipv6_address(host):
443+
host = f"[{host}]"
444+
445+
if host[-1] == ".":
446+
# Remove all trailing dots from the netloc as while
447+
# they are valid FQDNs in DNS, TLS validation fails.
448+
# See https://github.com/aio-libs/aiohttp/issues/3636.
449+
# To avoid string manipulation we only call rstrip if
450+
# the last character is a dot.
451+
host = host.rstrip(".")
452+
453+
# If explicit port is not None, it means that the port was
454+
# explicitly specified in the URL. In this case we check
455+
# if its not the default port for the scheme and add it to
456+
# the host header. We check explicit_port first because
457+
# yarl caches explicit_port and its likely to already be
458+
# in the cache and non-default port URLs are far less common.
459+
explicit_port = self.url.explicit_port
460+
if explicit_port is not None and not self.url.is_default_port():
461+
host = f"{host}:{explicit_port}"
462+
463+
self.headers[hdrs.HOST] = host
464+
465+
if not headers:
466+
return
467+
468+
if isinstance(headers, (dict, MultiDictProxy, MultiDict)):
469+
headers = headers.items()
470+
471+
for key, value in headers: # type: ignore[misc]
472+
# A special case for Host header
473+
if key.lower() == "host":
474+
self.headers[key] = value
475+
else:
476+
self.headers.add(key, value)
458477

459478
def update_auto_headers(self, skip_auto_headers: Optional[Iterable[str]]) -> None:
460479
if skip_auto_headers is not None:

0 commit comments

Comments
 (0)