Fix SessionHttpContext to delegate attributes via __getattr__

The previous implementation eagerly copied ASGI-specific attributes
(pathsend, receive, send) from the wrapped context, which crashed under
RSGI because RsgiContext does not have those attributes. Now
SessionHttpContext delegates all non-overridden attributes to the wrapped
context via __getattr__, making it protocol-agnostic.
This commit is contained in:
2026-07-23 22:09:59 +08:00
parent 3ebf079533
commit 65f1b79ce8
@@ -15,6 +15,10 @@ class SessionHttpContext(HttpContext):
Works with any concrete ``HttpContext`` (ASGI or RSGI) because it only
relies on the abstract send methods, which all implementations share.
Attributes not explicitly overridden are delegated to the wrapped context
via ``__getattr__``, so protocol-specific fields (``pathsend``,
``receive``/``send`` for ASGI, ``protocol`` for RSGI, etc.) are passed
through transparently.
"""
def __init__(
@@ -23,20 +27,14 @@ class SessionHttpContext(HttpContext):
session: Session,
cookie_injector: Callable[[], Optional[str]],
) -> None:
self._ctx = ctx
self.session = session
self._cookie_injector = cookie_injector
self.pathsend = ctx.pathsend
self.receive = ctx.receive
self.send = ctx.send
self.scheme = ctx.scheme
self.method = ctx.method
self.path = ctx.path
self.query_string = ctx.query_string
self.headers = ctx.headers
self.client = ctx.client
self.server = ctx.server
self.request_body = ctx.request_body
object.__setattr__(self, '_ctx', ctx)
object.__setattr__(self, 'session', session)
object.__setattr__(self, '_cookie_injector', cookie_injector)
def __getattr__(self, name: str) -> Any:
if name == '_ctx':
raise AttributeError(name)
return getattr(self._ctx, name)
def _inject_cookie(self, headers: Optional[Mapping[str, StrOrStrings]]) -> Optional[Mapping[str, StrOrStrings]]:
cookie_value = self._cookie_injector()