Skip to content

Commit

Permalink
Merge pull request #6062 from readthedocs/davidfischer/ipv6-fix
Browse files Browse the repository at this point in the history
IPv6 in X-Forwarded-For fix
  • Loading branch information
davidfischer authored Aug 9, 2019
2 parents 9864ef1 + 21ac26f commit e53af66
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 2 deletions.
16 changes: 15 additions & 1 deletion readthedocs/analytics/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,19 @@ def test_anonymize_ua(self):
)

def test_get_client_ip_with_x_forwarded_for(self):

# only client's ip is present
request = RequestFactory().get('/')
request.META['HTTP_X_FORWARDED_FOR'] = '203.0.113.195'
client_ip = get_client_ip(request)
self.assertEqual(client_ip, '203.0.113.195')

# only client's ip is present
request = RequestFactory().get('/')
ip = '2001:abc:def:012:345:6789:abcd:ef12'
request.META['HTTP_X_FORWARDED_FOR'] = ip
client_ip = get_client_ip(request)
self.assertEqual(client_ip, ip)

# proxy1 and proxy2 are present along with client's ip
request = RequestFactory().get('/')
request.META['HTTP_X_FORWARDED_FOR'] = '203.0.113.195, 70.41.3.18, 150.172.238.178'
Expand All @@ -53,6 +59,14 @@ def test_get_client_ip_with_x_forwarded_for(self):
client_ip = get_client_ip(request)
self.assertEqual(client_ip, '203.0.113.195')

# client ip (ipv6), other clients with port
request = RequestFactory().get('/')
ip = '2001:abc:def:012:345:6789:abcd:ef12'
x_forwarded_for = f'{ip}, 203.0.113.195:8080, 70.41.3.18'
request.META['HTTP_X_FORWARDED_FOR'] = x_forwarded_for
client_ip = get_client_ip(request)
self.assertEqual(client_ip, ip)

# client ip with port but not proxy1 and proxy2
request = RequestFactory().get('/')
request.META['HTTP_X_FORWARDED_FOR'] = '203.0.113.195:8080'
Expand Down
4 changes: 3 additions & 1 deletion readthedocs/analytics/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ def get_client_ip(request):
client_ip = x_forwarded_for.split(',')[0].strip()

# Removing the port number (if present)
client_ip = client_ip.rsplit(':')[0]
# But be careful about IPv6 addresses
if client_ip.count(':') == 1:
client_ip = client_ip.rsplit(':', maxsplit=1)[0]
else:
client_ip = request.META.get('REMOTE_ADDR', None)

Expand Down

0 comments on commit e53af66

Please sign in to comment.