中间件#
中间件可以用于包装 Quart 应用实例并更改 ASGI 进程。一个非常简单的示例是根据是否存在标头来拒绝请求,
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,
})
虽然中间件始终可以作为应用实例的包装器使用,但最好将其分配给并包装 asgi_app
属性,
quart_app.asgi_app = RejectMiddleware(quart_app.asgi_app)
因为这样可以确保在任何测试代码中应用中间件。
您可以组合多个中间件包装器,
quart_app.asgi_app = RejectMiddleware(quart_app.asgi_app)
quart_app.asgi_app = AdditionalMiddleware(quart_app.asgi_app)
并使用任何 ASGI 中间件。
警告
中间件在任何 Quart 代码之前运行,这意味着如果中间件返回响应,则不会运行任何 Quart 功能或 Quart 扩展。