feat(cache): add 30-day browser cache for uploaded images (middleware + S3 CacheControl)
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
@echo off
|
@echo off
|
||||||
cd /d "%~dp0"
|
cd /d "%~dp0"
|
||||||
call .venv\Scripts\activate.bat
|
call .venv\Scripts\activate.bat
|
||||||
python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
|
@rem python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
|
||||||
pause
|
pause
|
||||||
|
|||||||
15
app/main.py
15
app/main.py
@@ -1,7 +1,8 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI, Request, Response
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
|
from starlette.middleware.base import BaseHTTPMiddleware
|
||||||
|
|
||||||
from app.config import UPLOAD_DIR
|
from app.config import UPLOAD_DIR
|
||||||
from app.database import init_db
|
from app.database import init_db
|
||||||
@@ -13,6 +14,18 @@ UPLOAD_DIR.mkdir(exist_ok=True)
|
|||||||
app.mount("/static", StaticFiles(directory=str(Path(__file__).resolve().parent / "static")), name="static")
|
app.mount("/static", StaticFiles(directory=str(Path(__file__).resolve().parent / "static")), name="static")
|
||||||
app.mount("/uploads", StaticFiles(directory=str(UPLOAD_DIR)), name="uploads")
|
app.mount("/uploads", StaticFiles(directory=str(UPLOAD_DIR)), name="uploads")
|
||||||
|
|
||||||
|
|
||||||
|
# Browser cache: 30 days for uploaded images (they never change)
|
||||||
|
class CacheControlMiddleware(BaseHTTPMiddleware):
|
||||||
|
async def dispatch(self, request: Request, call_next):
|
||||||
|
response: Response = await call_next(request)
|
||||||
|
if request.url.path.startswith("/uploads/"):
|
||||||
|
response.headers["Cache-Control"] = "public, max-age=2592000, immutable"
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
app.add_middleware(CacheControlMiddleware)
|
||||||
|
|
||||||
app.include_router(web.router)
|
app.include_router(web.router)
|
||||||
app.include_router(api.router)
|
app.include_router(api.router)
|
||||||
|
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ class S3Storage:
|
|||||||
def put(self, key: str, data: bytes, content_type: str = "image/jpeg") -> str:
|
def put(self, key: str, data: bytes, content_type: str = "image/jpeg") -> str:
|
||||||
self._client.put_object(
|
self._client.put_object(
|
||||||
Bucket=self.bucket, Key=key, Body=data, ContentType=content_type,
|
Bucket=self.bucket, Key=key, Body=data, ContentType=content_type,
|
||||||
|
CacheControl="public, max-age=2592000, immutable",
|
||||||
)
|
)
|
||||||
return key
|
return key
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user