Changeset View
Changeset View
Standalone View
Standalone View
looper/utils.py
| import re | |||||
| IPV4_WITH_PORT = re.compile(r"([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+):[0-9]+") | |||||
| """Regexp matching an IPv4 address with a port number.""" | |||||
| IPV6_WITH_PORT = re.compile(r"\[([0-9:]+)\]:[0-9]+") | |||||
| """Regexp matching an IPv6 address with a port number.""" | |||||
| def get_client_ip(request): | def get_client_ip(request): | ||||
| """Returns the IP of the request, accounting for the possibility of being | """Returns the IP of the request, accounting for the possibility of being | ||||
| behind a proxy. | behind a proxy. | ||||
| Context not available. | |||||
| x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR', None) | x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR', None) | ||||
| if x_forwarded_for: | if x_forwarded_for: | ||||
| # X_FORWARDED_FOR returns client1, proxy1, proxy2,... | # X_FORWARDED_FOR returns client1, proxy1, proxy2,... | ||||
| return x_forwarded_for.split(', ', 1)[0].strip() | remote_addr = x_forwarded_for.split(', ', 1)[0].strip() | ||||
| return _remove_port_nr(remote_addr) | |||||
| remote_addr = request.META.get('REMOTE_ADDR', '') | remote_addr = request.META.get('REMOTE_ADDR', '') | ||||
| if not remote_addr: | if not remote_addr: | ||||
| Context not available. | |||||
| if ',' in remote_addr: | if ',' in remote_addr: | ||||
| return '' | return '' | ||||
| return _remove_port_nr(remote_addr) | |||||
| def _remove_port_nr(remote_addr: str) -> str: | |||||
| # Occasionally the port number is included in REMOTE_ADDR. | |||||
| # This needs to be filtered out so that downstream requests | |||||
| # can just interpret the value as actual IP address. | |||||
| if len(remote_addr) > 128: | |||||
| # Prevent DoS attacks by not allowing obvious nonsense. | |||||
| return '' | |||||
| if ':' not in remote_addr: | |||||
| return remote_addr | |||||
| ipv4_with_port_match = IPV4_WITH_PORT.match(remote_addr) | |||||
| if ipv4_with_port_match: | |||||
| return ipv4_with_port_match.group(1) | |||||
| ipv6_with_port_match = IPV6_WITH_PORT.match(remote_addr) | |||||
| if ipv6_with_port_match: | |||||
| return ipv6_with_port_match.group(1) | |||||
| return remote_addr | return remote_addr | ||||
| Context not available. | |||||