Login

Add get_addr() method to request object

Author:
nikmolnar
Posted:
December 13, 2012
Language:
Python
Version:
1.4
Tags:
address request get-addr client remote-addr header x-forwarded-for ip
Score:
1 (after 1 ratings)

I thought it would be useful to have a get_addr() method available on request objects, similar to the get_host() provided by Django. This middleware will add a get_addr() method to requests which uses the X-Forwarded-For header (useful if you're behind a proxy) if it's present and you have the USE_X_FORWARDED_FOR header set to True (default is False) and otherwise will use the REMOTE_ADDR environment variable. Note that if you are not behind a proxy and have USE_X_FORWARDED_FOR set to True, then clients can spoof their IP by simply setting the X-Forwarded-For header.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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__)

More like this

  1. Get Client IP Behind Proxy by brianjaystanley 3 years, 5 months ago
  2. Single Django App behind multiple Apache Proxies by chadmaine 7 years, 11 months ago
  3. Add Extra Headers to Test Client Requests by luftyluft 6 years, 8 months ago
  4. Effective content caching for mass-load site using redirect feature by nnseva 3 years, 8 months ago
  5. nginx x-accel-redirect protection of static files by sean 7 years, 4 months ago

Comments

Please login first before commenting.