Files
plm-lottery/tests/unit/test_client_ip.py
T

44 lines
1.5 KiB
Python
Raw Normal View History

"""app.api.client_ip is shared by the login/registration throttles (B-33) and
the SSE per-IP subscriber cap (B-38) — both depend on it correctly preferring
X-Forwarded-For (Caddy reverse-proxies every request, see Caddyfile) over
request.client.host, which would otherwise be the proxy's own address."""
from starlette.requests import Request
from app.api.client_ip import client_ip
def _request(*, forwarded: str | None = None, client_host: str | None = "127.0.0.1") -> Request:
headers = [(b"x-forwarded-for", forwarded.encode())] if forwarded else []
scope = {
"type": "http",
"headers": headers,
"client": (client_host, 12345) if client_host else None,
}
return Request(scope)
def test_client_ip_prefers_x_forwarded_for():
request = _request(forwarded="5.6.7.8", client_host="10.0.0.1")
assert client_ip(request) == "5.6.7.8"
def test_client_ip_takes_the_first_hop_of_a_forwarded_chain():
request = _request(forwarded="5.6.7.8, 10.0.0.1, 172.17.0.1")
assert client_ip(request) == "5.6.7.8"
def test_client_ip_strips_whitespace():
request = _request(forwarded=" 5.6.7.8 , 10.0.0.1")
assert client_ip(request) == "5.6.7.8"
def test_client_ip_falls_back_to_request_client_without_the_header():
request = _request(forwarded=None, client_host="10.0.0.1")
assert client_ip(request) == "10.0.0.1"
def test_client_ip_falls_back_to_unknown_with_neither():
request = _request(forwarded=None, client_host=None)
assert client_ip(request) == "unknown"