diff --git a/src/web_api.py b/src/web_api.py index 4b06ec5..03ac09a 100644 --- a/src/web_api.py +++ b/src/web_api.py @@ -348,6 +348,35 @@ def _send_umami_event(path: str, method: str, status: int, host: str, user_agent pass # analytics must never affect API behavior +# Cache-Control by path: lets browsers and any edge cache (e.g. Cloudflare in +# front of Caddy) absorb repeat traffic — the public uplink is the scarce +# resource. Max-ages mirror the server-side cache TTLs / data cadence. +_CACHE_CONTROL_RULES = ( + ("/static/", "public, max-age=3600"), + ("/measurements/latest", "public, max-age=30"), + ("/api/hii/", "public, max-age=60"), + ("/measurements/history", "public, max-age=300"), + ("/forecast", "public, max-age=120"), + ("/api/stats", "public, max-age=300"), + ("/stations", "public, max-age=300"), +) + + +@app.middleware("http") +async def cache_control_headers(request, call_next): + response = await call_next(request) + if request.method == "GET" and response.status_code == 200: + path = request.url.path + if path == "/": + response.headers.setdefault("Cache-Control", "public, max-age=120") + else: + for prefix, value in _CACHE_CONTROL_RULES: + if path.startswith(prefix): + response.headers.setdefault("Cache-Control", value) + break + return response + + @app.middleware("http") async def umami_api_tracking(request, call_next): response = await call_next(request)