openfoodfacts_proxy.routes.common
[docs]
module
openfoodfacts_proxy.routes.common
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 | from fastapi import Request
from fastapi.responses import RedirectResponse
ALL_HTTP_METHODS = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
def get_client_ip(request: Request) -> str:
"""Extract the client IP, respecting X-Forwarded-For and X-Real-IP when present."""
forwarded = request.headers.get("x-forwarded-for")
if forwarded:
return forwarded.split(",")[0].strip()
real_ip = request.headers.get("x-real-ip")
if real_ip:
return real_ip.strip()
return request.client.host if request.client else "unknown"
def build_upstream_url(request: Request, upstream_path: str | None = None) -> str:
"""Build the upstream URL preserving the incoming query string."""
settings = request.app.state.settings
path = upstream_path or request.url.path
path = path.lstrip("/")
url = f"{settings.off_base_url.rstrip('/')}/{path}"
if request.url.query:
return f"{url}?{request.url.query}"
return url
def redirect_to_upstream(
request: Request,
upstream_path: str | None = None,
*,
status_code: int = 307,
) -> RedirectResponse:
"""Return a redirect to the upstream OFF API.
Redirecting keeps the effective OFF rate limit tied to the client IP instead of
collapsing all traffic behind this server's IP address.
"""
return RedirectResponse(
url=build_upstream_url(request, upstream_path),
status_code=status_code,
headers={"X-Proxy-Source": "upstream-redirect"},
)
|