diff --git a/.travis.yml b/.travis.yml index 956d269..f23eb95 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ python: - pypy env: - - DJANGO="django==1.7" + - DJANGO="django==1.7.7" - DJANGO="django==1.6.7" - DJANGO="django==1.4.15" @@ -33,6 +33,6 @@ matrix: - python: "3.2" env: DJANGO="django==1.4.15" - python: "2.6" - env: DJANGO="django==1.7" + env: DJANGO="django==1.7.7" script: python manage.py test diff --git a/CHANGELOG.md b/CHANGELOG.md index 46081a0..e3e6e37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.1.1 + +Enhancement: + + - Support for Left2Right or Right2Left Proxy IP Lookup + ## 0.1.0 Enhancement: diff --git a/README.md b/README.md index cddb20e..ad3d4c7 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,15 @@ How to use # we have an ip address for user else: # we don't have an ip address for user + + # By default the left most address in the `HTTP_X_FORWARDED_FOR` is returned. However, depending on your + # preference and needs, you can change this behavior by passing the `right_most_proxy=True` to the API. + # Please note that not all proxies are equal. So left to right or right to left is not a rule that all + # proxy servers follow. + from ipware.ip import get_ip + ip = get_ip(request, right_most_proxy=True) + # OR + ip = get_real_ip(request, right_most_proxy=True) ``` Advanced users: diff --git a/ipware/__init__.py b/ipware/__init__.py index f6ee460..6c060aa 100644 --- a/ipware/__init__.py +++ b/ipware/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -__version__ = '0.1.0' +__version__ = '0.1.1' default_app_config = 'ipware.apps.AppConfig' diff --git a/ipware/ip.py b/ipware/ip.py index ebd756f..ffe082c 100644 --- a/ipware/ip.py +++ b/ipware/ip.py @@ -4,7 +4,7 @@ from .defaults import IPWARE_NON_PUBLIC_IP_PREFIX -def get_ip(request, real_ip_only=False): +def get_ip(request, real_ip_only=False, right_most_proxy=False): """ Returns client's best-matched ip-address, or None """ @@ -13,6 +13,8 @@ def get_ip(request, real_ip_only=False): value = request.META.get(key, '').strip() if value != '': ips = [ip.strip().lower() for ip in value.split(',')] + if right_most_proxy: + ips = reversed(ips) for ip_str in ips: if ip_str and is_valid_ip(ip_str): if not ip_str.startswith(IPWARE_NON_PUBLIC_IP_PREFIX): @@ -26,8 +28,8 @@ def get_ip(request, real_ip_only=False): return best_matched_ip -def get_real_ip(request): +def get_real_ip(request, right_most_proxy=False): """ Returns client's best-matched `real` ip-address, or None """ - return get_ip(request, real_ip_only=True) + return get_ip(request, real_ip_only=True, right_most_proxy=right_most_proxy) diff --git a/ipware/tests.py b/ipware/tests.py index 2ddf06c..ea79ae4 100644 --- a/ipware/tests.py +++ b/ipware/tests.py @@ -18,6 +18,36 @@ def test_x_forwarded_for_multiple(self): ip = get_real_ip(request) self.assertEqual(ip, "198.84.193.157") + def test_x_forwarded_for_multiple_left_most_ip(self): + request = HttpRequest() + request.META = { + 'HTTP_X_FORWARDED_FOR': '192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139', + 'HTTP_X_REAL_IP': '177.139.233.132', + 'REMOTE_ADDR': '177.139.233.133', + } + ip = get_real_ip(request) + self.assertEqual(ip, "198.84.193.157") + + def test_x_forwarded_for_multiple_right_most_ip(self): + request = HttpRequest() + request.META = { + 'HTTP_X_FORWARDED_FOR': '192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139', + 'HTTP_X_REAL_IP': '177.139.233.132', + 'REMOTE_ADDR': '177.139.233.133', + } + ip = get_real_ip(request, right_most_proxy=True) + self.assertEqual(ip, "177.139.233.139") + + def test_x_forwarded_for_multiple_right_most_ip_private(self): + request = HttpRequest() + request.META = { + 'HTTP_X_FORWARDED_FOR': '192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139', + 'HTTP_X_REAL_IP': '177.139.233.132', + 'REMOTE_ADDR': '177.139.233.133', + } + ip = get_real_ip(request, right_most_proxy=True) + self.assertEqual(ip, "177.139.233.139") + def test_x_forwarded_for_multiple_bad_address(self): request = HttpRequest() request.META = {