Skip to content

Commit 07c4372

Browse files
[PR #10714/75bbc03e backport][3.11] Only fetch SSLContext and peername once per connection (#10734)
Co-authored-by: J. Nick Koston <[email protected]>
1 parent 377a1f8 commit 07c4372

File tree

4 files changed

+32
-4
lines changed

4 files changed

+32
-4
lines changed

CHANGES/10714.misc.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improved web server performance when connection can be reused -- by :user:`bdraco`.

aiohttp/test_utils.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,10 @@ def make_mocked_request(
730730
if protocol is sentinel:
731731
protocol = mock.Mock()
732732
protocol.transport = transport
733+
type(protocol).peername = mock.PropertyMock(
734+
return_value=transport.get_extra_info("peername")
735+
)
736+
type(protocol).ssl_context = mock.PropertyMock(return_value=sslcontext)
733737

734738
if writer is sentinel:
735739
writer = mock.Mock()

aiohttp/web_protocol.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import attr
2626
import yarl
27+
from propcache import under_cached_property
2728

2829
from .abc import AbstractAccessLogger, AbstractStreamWriter
2930
from .base_protocol import BaseProtocol
@@ -47,6 +48,8 @@
4748
__all__ = ("RequestHandler", "RequestPayloadError", "PayloadAccessError")
4849

4950
if TYPE_CHECKING:
51+
import ssl
52+
5053
from .web_server import Server
5154

5255

@@ -167,6 +170,7 @@ class RequestHandler(BaseProtocol):
167170
"_current_request",
168171
"_timeout_ceil_threshold",
169172
"_request_in_progress",
173+
"_cache",
170174
)
171175

172176
def __init__(
@@ -246,13 +250,34 @@ def __init__(
246250
self._close = False
247251
self._force_close = False
248252
self._request_in_progress = False
253+
self._cache: dict[str, Any] = {}
249254

250255
def __repr__(self) -> str:
251256
return "<{} {}>".format(
252257
self.__class__.__name__,
253258
"connected" if self.transport is not None else "disconnected",
254259
)
255260

261+
@under_cached_property
262+
def ssl_context(self) -> Optional["ssl.SSLContext"]:
263+
"""Return SSLContext if available."""
264+
return (
265+
None
266+
if self.transport is None
267+
else self.transport.get_extra_info("sslcontext")
268+
)
269+
270+
@under_cached_property
271+
def peername(
272+
self,
273+
) -> Optional[Union[str, Tuple[str, int, int, int], Tuple[str, int]]]:
274+
"""Return peername if available."""
275+
return (
276+
None
277+
if self.transport is None
278+
else self.transport.get_extra_info("peername")
279+
)
280+
256281
@property
257282
def keepalive_timeout(self) -> float:
258283
return self._keepalive_timeout

aiohttp/web_request.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,8 @@ def __init__(
198198
self._client_max_size = client_max_size
199199
self._loop = loop
200200

201-
transport = protocol.transport
202-
assert transport is not None
203-
self._transport_sslcontext = transport.get_extra_info("sslcontext")
204-
self._transport_peername = transport.get_extra_info("peername")
201+
self._transport_sslcontext = protocol.ssl_context
202+
self._transport_peername = protocol.peername
205203

206204
if remote is not None:
207205
self._cache["remote"] = remote

0 commit comments

Comments
 (0)