http_limit.py 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. from math import ceil
  2. from typing import NoReturn
  3. from fastapi import Request, Response
  4. from starlette.websockets import WebSocket
  5. from app.core.exceptions import CustomException
  6. def http_limit_callback(request: Request, response: Response, expire: int) -> NoReturn:
  7. """
  8. HTTP 触发限流时的默认回调:抛出 429。
  9. 参数:
  10. - request (Request): 当前请求。
  11. - response (Response): 当前响应(未直接使用,保留与限流器签名一致)。
  12. - expire (int): 剩余冷却毫秒数。
  13. 返回:
  14. - 无(始终抛出 CustomException)。
  15. """
  16. expires = ceil(expire / 30)
  17. raise CustomException(
  18. status_code=429,
  19. msg="请求过于频繁,请稍后重试!",
  20. data={"Retry-After": str(expires)},
  21. )
  22. async def ws_limit_callback(ws: WebSocket, expire: int) -> None:
  23. """
  24. WebSocket 触发限流时的默认回调:关闭连接。
  25. 参数:
  26. - ws (WebSocket): 当前 WebSocket。
  27. - expire (int): 剩余冷却毫秒数。
  28. 返回:
  29. - None
  30. """
  31. expires = ceil(expire / 30)
  32. await ws.close(code=1008, reason=f"请求过于频繁,请稍后重试!{expires} 秒后重试")