Add global middleware ordering

This commit is contained in:
Adam Hopkins 2022-08-17 21:57:07 +03:00
parent 09b59d34fe
commit beb5c62767
No known key found for this signature in database
GPG Key ID: 9F85EE6C807303FB
4 changed files with 55 additions and 17 deletions

View File

@ -754,12 +754,11 @@ class Sanic(BaseSanic, RunnerMixin, metaclass=TouchUpMeta):
# -------------------------------------------- # # -------------------------------------------- #
# Request Middleware # Request Middleware
# -------------------------------------------- # # -------------------------------------------- #
if ( if run_middleware:
run_middleware middleware = (
and request.route request.route and request.route.extra.request_middleware
and request.route.extra.request_middleware ) or self.request_middleware
): response = await self._run_request_middleware(request, middleware)
response = await self._run_request_middleware(request)
# No middleware results # No middleware results
if not response: if not response:
try: try:
@ -845,6 +844,7 @@ class Sanic(BaseSanic, RunnerMixin, metaclass=TouchUpMeta):
Coroutine[Any, Any, Optional[BaseHTTPResponse]], Coroutine[Any, Any, Optional[BaseHTTPResponse]],
] ]
] = None ] = None
run_middleware = True
try: try:
await self.dispatch( await self.dispatch(
@ -889,8 +889,11 @@ class Sanic(BaseSanic, RunnerMixin, metaclass=TouchUpMeta):
# -------------------------------------------- # # -------------------------------------------- #
# Request Middleware # Request Middleware
# -------------------------------------------- # # -------------------------------------------- #
run_middleware = False
if request.route.extra.request_middleware: 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 # No middleware results
if not response: if not response:
@ -960,7 +963,9 @@ class Sanic(BaseSanic, RunnerMixin, metaclass=TouchUpMeta):
raise raise
except Exception as e: except Exception as e:
# Response Generation Failed # 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( async def _websocket_handler(
self, handler, request, *args, subprotocols=None, **kwargs self, handler, request, *args, subprotocols=None, **kwargs
@ -1028,10 +1033,12 @@ class Sanic(BaseSanic, RunnerMixin, metaclass=TouchUpMeta):
# Execution # 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 request._request_middleware_started = True
for middleware in request.route.extra.request_middleware: for middleware in middleware_collection:
await self.dispatch( await self.dispatch(
"http.middleware.before", "http.middleware.before",
inline=True, inline=True,
@ -1060,8 +1067,10 @@ class Sanic(BaseSanic, RunnerMixin, metaclass=TouchUpMeta):
return response return response
return None return None
async def _run_response_middleware(self, request, response): # no cov async def _run_response_middleware(
for middleware in request.route.extra.response_middleware: self, request, response, middleware_collection
): # no cov
for middleware in middleware_collection:
await self.dispatch( await self.dispatch(
"http.middleware.before", "http.middleware.before",
inline=True, inline=True,

View File

@ -104,13 +104,39 @@ class MiddlewareMixin(metaclass=SanicMeta):
self.named_response_middleware.get(route.name, deque()), self.named_response_middleware.get(route.name, deque()),
location=MiddlewareLocation.RESPONSE, 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, request_middleware,
key=attrgetter("order"), key=attrgetter("order"),
reverse=True, reverse=True,
) )
route.extra.response_middleware = sorted( )
self.response_middleware = deque(
sorted(
response_middleware, response_middleware,
key=attrgetter("order"), key=attrgetter("order"),
reverse=True, reverse=True,
)[::-1] )[::-1]
)

View File

@ -334,9 +334,12 @@ class Request:
response = await response # type: ignore response = await response # type: ignore
# Run response middleware # Run response middleware
try: 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( response = await self.app._run_response_middleware(
self, response self, response, middleware
) )
except CancelledErrors: except CancelledErrors:
raise raise

View File

@ -84,7 +84,7 @@ ujson = "ujson>=1.35" + env_dependency
uvloop = "uvloop>=0.5.3" + env_dependency uvloop = "uvloop>=0.5.3" + env_dependency
types_ujson = "types-ujson" + env_dependency types_ujson = "types-ujson" + env_dependency
requirements = [ requirements = [
"sanic-routing>=22.3.0,<22.6.0", "sanic-routing>=22.8.0",
"httptools>=0.0.10", "httptools>=0.0.10",
uvloop, uvloop,
ujson, ujson,