from django.conf import settings
from django.core.exceptions import SuspiciousOperation
import types
import re
USE_X_FORWARDED_FOR = getattr(settings, 'USE_X_FORWARDED_FOR', False)
ip_validation_re = re.compile(r"^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$")
class RequestAddrMiddleware(object):
"""
Adds a get_addr() method to the request object which returns an IP address based on X-Forwarded-For header if
present and USE_X_FORWARDED_FOR setting is True (default is False) or REMOTE_ADDR meta attribute otherwise.
"""
def process_request(self, request):
"""Called on each request, before Django decides which view to execute."""
def get_addr(inst):
"""Returns the client IP address using the environment or request headers."""
if USE_X_FORWARDED_FOR and 'HTTP_X_FORWARDED_FOR' in inst.META:
addr = inst.META['HTTP_X_FORWARDED_FOR'].split(",",1)[0].strip()
elif 'REMOTE_ADDR' in inst.META:
addr = inst.META['REMOTE_ADDR']
else:
addr = "127.0.0.1" #Couldn't determine actual client IP!
if not ip_validation_re.match(addr):
raise SuspiciousOperation("Invalid client IP: %s" % addr)
return addr
request.get_addr = types.MethodType(get_addr, request, request.__class__)
Comments