When two routes share the same parameter at the same node position
(e.g. GET /restaurants/${id} and GET /restaurants/${id}/menu),
reuse the existing equivalent matcher instead of raising a conflict.
Non-equivalent matchers (different names, kinds, or glob patterns)
at the same node for the same method still raise ValueError.
- AsgiContext and AsgiWebSocket now default missing scope key
to 'http' / 'ws' respectively (Daphne omits it for websocket scopes)
- Add regression test for websocket scope without scheme
- Update example/session.py WS handler to read the session; cookie must
be set via HTTP first because common ASGI servers ignore the headers
field on websocket.accept
- Update README with the same caveat about Granian/Daphne/curl
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.
Replace wrapper-based SessionMiddleware/OIDCApp with KayaMixin subclasses
applied via KayaApp(mixins=[...]). Mixins hook into handle_request and
handle_websocket via before/after hooks, so both ASGI and RSGI keep working.
Mixin dependencies are applied automatically and deduplicated.