diff --git a/sanic/asgi.py b/sanic/asgi.py index 2614016866..107e8931e0 100644 --- a/sanic/asgi.py +++ b/sanic/asgi.py @@ -163,6 +163,13 @@ async def create( instance.request_body = True instance.request.conn_info = ConnInfo(instance.transport) + await sanic_app.dispatch( + "http.lifecycle.request", + inline=True, + context={"request": instance.request}, + fail_not_found=False, + ) + return instance async def read(self) -> Optional[bytes]: diff --git a/tests/test_asgi.py b/tests/test_asgi.py index 49bd732b18..d1be5ff2e7 100644 --- a/tests/test_asgi.py +++ b/tests/test_asgi.py @@ -13,6 +13,7 @@ from sanic.request import Request from sanic.response import json, text from sanic.server.websockets.connection import WebSocketConnection +from sanic.signals import RESERVED_NAMESPACES @pytest.fixture @@ -513,3 +514,34 @@ def forbidden(request): _, response = await app.asgi_client.get("/error-prone") assert response.status_code == 403 + + +@pytest.mark.asyncio +async def test_signals_triggered(app): + @app.get("/test_signals_triggered") + async def _request(request): + return text("test_signals_triggered") + + signals_triggered = [] + signals_expected = [ + # "http.lifecycle.begin", + # "http.lifecycle.read_head", + "http.lifecycle.request", + "http.lifecycle.handle", + "http.routing.before", + "http.routing.after", + "http.lifecycle.response", + # "http.lifecycle.send", + # "http.lifecycle.complete", + ] + + def signal_handler(signal): + return lambda *a, **kw: signals_triggered.append(signal) + + for signal in RESERVED_NAMESPACES["http"]: + app.signal(signal)(signal_handler(signal)) + + _, response = await app.asgi_client.get("/test_signals_triggered") + assert response.status_code == 200 + assert response.text == "test_signals_triggered" + assert signals_triggered == signals_expected