From beb5c627671ceedf5b3b82e7270a30024a47ba60 Mon Sep 17 00:00:00 2001 From: Adam Hopkins Date: Wed, 17 Aug 2022 21:57:07 +0300 Subject: [PATCH] Add global middleware ordering --- sanic/app.py | 33 +++++++++++++++++++++------------ sanic/mixins/middleware.py | 30 ++++++++++++++++++++++++++++-- sanic/request.py | 7 +++++-- setup.py | 2 +- 4 files changed, 55 insertions(+), 17 deletions(-) diff --git a/sanic/app.py b/sanic/app.py index 237f818c..26256b9d 100644 --- a/sanic/app.py +++ b/sanic/app.py @@ -754,12 +754,11 @@ class Sanic(BaseSanic, RunnerMixin, metaclass=TouchUpMeta): # -------------------------------------------- # # Request Middleware # -------------------------------------------- # - if ( - run_middleware - and request.route - and request.route.extra.request_middleware - ): - response = await self._run_request_middleware(request) + if run_middleware: + middleware = ( + request.route and request.route.extra.request_middleware + ) or self.request_middleware + response = await self._run_request_middleware(request, middleware) # No middleware results if not response: try: @@ -845,6 +844,7 @@ class Sanic(BaseSanic, RunnerMixin, metaclass=TouchUpMeta): Coroutine[Any, Any, Optional[BaseHTTPResponse]], ] ] = None + run_middleware = True try: await self.dispatch( @@ -889,8 +889,11 @@ class Sanic(BaseSanic, RunnerMixin, metaclass=TouchUpMeta): # -------------------------------------------- # # Request Middleware # -------------------------------------------- # + run_middleware = False if request.route.extra.request_middleware: - response = await self._run_request_middleware(request) + response = await self._run_request_middleware( + request, request.route.extra.request_middleware + ) # No middleware results if not response: @@ -960,7 +963,9 @@ class Sanic(BaseSanic, RunnerMixin, metaclass=TouchUpMeta): raise except Exception as e: # Response Generation Failed - await self.handle_exception(request, e, run_middleware=False) + await self.handle_exception( + request, e, run_middleware=run_middleware + ) async def _websocket_handler( self, handler, request, *args, subprotocols=None, **kwargs @@ -1028,10 +1033,12 @@ class Sanic(BaseSanic, RunnerMixin, metaclass=TouchUpMeta): # Execution # -------------------------------------------------------------------- # - async def _run_request_middleware(self, request): # no cov + async def _run_request_middleware( + self, request, middleware_collection + ): # no cov request._request_middleware_started = True - for middleware in request.route.extra.request_middleware: + for middleware in middleware_collection: await self.dispatch( "http.middleware.before", inline=True, @@ -1060,8 +1067,10 @@ class Sanic(BaseSanic, RunnerMixin, metaclass=TouchUpMeta): return response return None - async def _run_response_middleware(self, request, response): # no cov - for middleware in request.route.extra.response_middleware: + async def _run_response_middleware( + self, request, response, middleware_collection + ): # no cov + for middleware in middleware_collection: await self.dispatch( "http.middleware.before", inline=True, diff --git a/sanic/mixins/middleware.py b/sanic/mixins/middleware.py index 7615477c..bea3976f 100644 --- a/sanic/mixins/middleware.py +++ b/sanic/mixins/middleware.py @@ -104,13 +104,39 @@ class MiddlewareMixin(metaclass=SanicMeta): self.named_response_middleware.get(route.name, deque()), location=MiddlewareLocation.RESPONSE, ) - route.extra.request_middleware = sorted( + route.extra.request_middleware = deque( + sorted( + request_middleware, + key=attrgetter("order"), + reverse=True, + ) + ) + route.extra.response_middleware = deque( + sorted( + response_middleware, + key=attrgetter("order"), + reverse=True, + )[::-1] + ) + request_middleware = Middleware.convert( + self.request_middleware, + location=MiddlewareLocation.REQUEST, + ) + response_middleware = Middleware.convert( + self.response_middleware, + location=MiddlewareLocation.RESPONSE, + ) + self.request_middleware = deque( + sorted( request_middleware, key=attrgetter("order"), reverse=True, ) - route.extra.response_middleware = sorted( + ) + self.response_middleware = deque( + sorted( response_middleware, key=attrgetter("order"), reverse=True, )[::-1] + ) diff --git a/sanic/request.py b/sanic/request.py index ae872d10..552ea955 100644 --- a/sanic/request.py +++ b/sanic/request.py @@ -334,9 +334,12 @@ class Request: response = await response # type: ignore # Run response middleware try: - if self.route and self.route.extra.response_middleware: + middleware = ( + self.route and self.route.extra.response_middleware + ) or self.app.response_middleware + if middleware: response = await self.app._run_response_middleware( - self, response + self, response, middleware ) except CancelledErrors: raise diff --git a/setup.py b/setup.py index f752a62e..f0a149a8 100644 --- a/setup.py +++ b/setup.py @@ -84,7 +84,7 @@ ujson = "ujson>=1.35" + env_dependency uvloop = "uvloop>=0.5.3" + env_dependency types_ujson = "types-ujson" + env_dependency requirements = [ - "sanic-routing>=22.3.0,<22.6.0", + "sanic-routing>=22.8.0", "httptools>=0.0.10", uvloop, ujson,