40 lines
1.2 KiB
Python
40 lines
1.2 KiB
Python
# retoor <retoor@molodetz.nl>
|
|
from urllib.parse import urlsplit
|
|
|
|
|
|
def client_ip(request):
|
|
real = request.headers.get("x-real-ip")
|
|
if real:
|
|
return real.strip()
|
|
forwarded = request.headers.get("x-forwarded-for")
|
|
if forwarded:
|
|
return forwarded.split(",")[0].strip()
|
|
return request.client.host if request.client else "unknown"
|
|
|
|
|
|
def safe_next(value, default="/"):
|
|
if not value or not isinstance(value, str):
|
|
return default
|
|
if not value.startswith("/") or value.startswith("//") or value.startswith("/\\"):
|
|
return default
|
|
if "\\" in value or "\r" in value or "\n" in value:
|
|
return default
|
|
return value
|
|
|
|
|
|
def redirect_back(request, default="/"):
|
|
referer = request.headers.get("referer")
|
|
if referer:
|
|
parts = urlsplit(referer)
|
|
if parts.netloc == request.url.netloc:
|
|
target = parts.path + (f"?{parts.query}" if parts.query else "")
|
|
return safe_next(target, default)
|
|
return safe_next(request.query_params.get("next"), default)
|
|
|
|
|
|
def is_secure_request(request):
|
|
proto = request.headers.get("x-forwarded-proto")
|
|
if proto:
|
|
return proto.split(",")[0].strip() == "https"
|
|
return request.url.scheme == "https"
|