Returns (host, port) for building absolute URIs. - Prefers X-Forwarded-Host/X-Forwarded-Port (nginx). - Falls back to Host header. - Returns None for port if using standard ports (80/443) to omit from URLs. - In dev, uses 5656 as a guess if port cannot be determined.
(request)
| 954 | |
| 955 | |
| 956 | def get_host_and_port(request): |
| 957 | """ |
| 958 | Returns (host, port) for building absolute URIs. |
| 959 | - Prefers X-Forwarded-Host/X-Forwarded-Port (nginx). |
| 960 | - Falls back to Host header. |
| 961 | - Returns None for port if using standard ports (80/443) to omit from URLs. |
| 962 | - In dev, uses 5656 as a guess if port cannot be determined. |
| 963 | """ |
| 964 | scheme = request.META.get("HTTP_X_FORWARDED_PROTO", request.scheme) |
| 965 | standard_port = "443" if scheme == "https" else "80" |
| 966 | |
| 967 | # 1. Try X-Forwarded-Host (may include port) - set by our nginx |
| 968 | xfh = request.META.get("HTTP_X_FORWARDED_HOST") |
| 969 | if xfh: |
| 970 | if ":" in xfh: |
| 971 | host, port = xfh.split(":", 1) |
| 972 | if port == standard_port: |
| 973 | return host, None |
| 974 | return host, port |
| 975 | else: |
| 976 | host = xfh |
| 977 | |
| 978 | port = request.META.get("HTTP_X_FORWARDED_PORT") |
| 979 | if port: |
| 980 | return host, None if port == standard_port else port |
| 981 | if request.META.get("HTTP_X_FORWARDED_PROTO"): |
| 982 | return host, None |
| 983 | |
| 984 | # 2. Try Host header |
| 985 | raw_host = request.get_host() |
| 986 | if ":" in raw_host: |
| 987 | host, port = raw_host.split(":", 1) |
| 988 | return host, None if port == standard_port else port |
| 989 | else: |
| 990 | host = raw_host |
| 991 | |
| 992 | # 3. Check for X-Forwarded-Port (when Host header has no port but we're behind a reverse proxy) |
| 993 | port = request.META.get("HTTP_X_FORWARDED_PORT") |
| 994 | if port: |
| 995 | return host, None if port == standard_port else port |
| 996 | |
| 997 | # 4. Behind a reverse proxy with no port info - assume standard port |
| 998 | if request.META.get("HTTP_X_FORWARDED_PROTO") or request.META.get("HTTP_X_FORWARDED_FOR"): |
| 999 | return host, None |
| 1000 | |
| 1001 | # 5. Try SERVER_PORT from META (only if NOT behind reverse proxy) |
| 1002 | port = request.META.get("SERVER_PORT") |
| 1003 | if port: |
| 1004 | return host, None if port == standard_port else port |
| 1005 | |
| 1006 | # 6. Dev fallback |
| 1007 | if os.environ.get("DISPATCHARR_ENV") == "dev" or host in ("localhost", "127.0.0.1"): |
| 1008 | return host, "5656" |
| 1009 | |
| 1010 | # 7. Final fallback: assume standard port for scheme |
| 1011 | return host, None |
| 1012 | |
| 1013 |
no test coverage detected