1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
.. _middleware:
Middleware
==========
Middleware can be used to wrap a Quart app instance and alter the ASGI
process. A very simple example would be to reject requests based on
the presence of a header,
.. code-block:: python
class RejectMiddleware:
def __init__(self, app):
self.app = app
async def __call__(self, scope, receive, send):
if "headers" not in scope:
return await self.app(scope, receive, send)
for header, value in scope['headers']:
if header.lower() == b'x-secret' and value == b'very-secret':
return await self.app(scope, receive, send)
return await self.error_response(receive, send)
async def error_response(self, receive, send):
await send({
'type': 'http.response.start',
'status': 401,
'headers': [(b'content-length', b'0')],
})
await send({
'type': 'http.response.body',
'body': b'',
'more_body': False,
})
Whilst middleware can always be used as a wrapper around the app
instance, it is best to assign to and wrap the ``asgi_app`` attribute,
.. code-block:: python
quart_app.asgi_app = RejectMiddleware(quart_app.asgi_app)
as this ensures that the middleware is applied in any test code.
You can combine multiple middleware wrappers,
.. code-block:: python
quart_app.asgi_app = RejectMiddleware(quart_app.asgi_app)
quart_app.asgi_app = AdditionalMiddleware(quart_app.asgi_app)
and use any ASGI middleware.
.. warning::
Middleware runs before any Quart code, which means that if the
middleware returns a response no Quart functionality nor any Quart
extensions will run.
|