diff --git a/app/router/v1/replay.py b/app/router/v1/replay.py index 884dabf..71ff6e4 100644 --- a/app/router/v1/replay.py +++ b/app/router/v1/replay.py @@ -15,6 +15,7 @@ from app.storage import StorageService from .router import router from fastapi import Depends, HTTPException, Query +from fastapi_limiter.depends import RateLimiter from pydantic import BaseModel from sqlmodel import col, select @@ -29,6 +30,7 @@ class ReplayModel(BaseModel): response_model=ReplayModel, name="获取回放文件", description="获取指定谱面的回放文件。", + dependencies=[Depends(RateLimiter(times=10, minutes=1))], ) async def download_replay( session: Database, diff --git a/app/router/v2/score.py b/app/router/v2/score.py index b887643..c54fce6 100644 --- a/app/router/v2/score.py +++ b/app/router/v2/score.py @@ -50,7 +50,6 @@ from app.models.score import ( ) from app.service.user_cache_service import get_user_cache_service from app.storage.base import StorageService -from app.storage.local import LocalStorageService from app.utils import utcnow from .router import router @@ -65,7 +64,8 @@ from fastapi import ( Query, Security, ) -from fastapi.responses import FileResponse, RedirectResponse +from fastapi.responses import RedirectResponse +from fastapi_limiter.depends import RateLimiter from httpx import HTTPError from pydantic import BaseModel from redis.asyncio import Redis @@ -912,6 +912,7 @@ async def reorder_score_pin( name="下载成绩回放", description="下载指定成绩的回放文件。", tags=["成绩"], + dependencies=[Depends(RateLimiter(times=10, minutes=1))], ) async def download_score_replay( score_id: int, @@ -960,14 +961,6 @@ async def download_score_replay( db.add(replay_watched_count) replay_watched_count.count += 1 await db.commit() - if isinstance(storage_service, LocalStorageService): - return FileResponse( - path=await storage_service.get_file_url(filepath), - filename=filepath, - media_type="application/x-osu-replay", - ) - else: - return RedirectResponse( - await storage_service.get_file_url(filepath), - 301, - ) + return RedirectResponse( + await storage_service.get_file_url(filepath), 301, headers={"Content-Type": "application/x-osu-replay"} + ) diff --git a/main.py b/main.py index 7a026db..72bef7a 100644 --- a/main.py +++ b/main.py @@ -110,6 +110,8 @@ v1 API 采用 API Key 鉴权,将 API Key 放入 Query `k` 中。 - 每分钟最多可以发送 1200 个请求 - 突发请求限制为每秒最多 200 个请求 + +此外,下载回放 API (`/api/v1/get_replay`, `/api/v2/scores/{score_id}/download`) 的速率限制为每分钟最多 10 个请求。 ''' if settings.enable_rate_limit else ""