1# -*- coding: utf-8 -*- 2 3import importlib 4 5from django.core.exceptions import ImproperlyConfigured 6from django.utils.translation import ugettext as _ 7 8from cms.utils.conf import get_cms_setting 9 10 11def get_request_ip_resolver(): 12 """ 13 This is the recommended method for obtaining the specified 14 CMS_REQUEST_IP_RESOLVER as it also does some basic import validation. 15 16 Returns the resolver or raises an ImproperlyConfigured exception. 17 """ 18 module, attribute = get_cms_setting('REQUEST_IP_RESOLVER').rsplit('.', 1) 19 try: 20 ip_resolver_module = importlib.import_module(module) 21 ip_resolver = getattr(ip_resolver_module, attribute) 22 except ImportError: 23 raise ImproperlyConfigured( 24 _('Unable to find the specified CMS_REQUEST_IP_RESOLVER module: ' 25 '"{0}".').format(module)) 26 except AttributeError: 27 raise ImproperlyConfigured( 28 _('Unable to find the specified CMS_REQUEST_IP_RESOLVER function: ' 29 '"{0}" in module "{1}".').format(attribute, module)) 30 return ip_resolver 31 32 33def default_request_ip_resolver(request): 34 """ 35 This is a hybrid request IP resolver that attempts should address most 36 cases. Order is important here. A 'REAL_IP' header supersedes an 37 'X_FORWARDED_FOR' header which supersedes a 'REMOTE_ADDR' header. 38 """ 39 return ( 40 real_ip(request) or 41 x_forwarded_ip(request) or 42 remote_addr_ip(request) 43 ) 44 45 46def real_ip(request): 47 """ 48 Returns the IP Address contained in the HTTP_X_REAL_IP headers, if 49 present. Otherwise, `None`. 50 51 Should handle Nginx and some other WSGI servers. 52 """ 53 return request.META.get('HTTP_X_REAL_IP') 54 55 56def remote_addr_ip(request): 57 """ 58 Returns the IP Address contained in the 'REMOTE_ADDR' header, if 59 present. Otherwise, `None`. 60 61 Should be suitable for local-development servers and some HTTP servers. 62 """ 63 return request.META.get('REMOTE_ADDR') 64 65 66def x_forwarded_ip(request): 67 """ 68 Returns the IP Address contained in the 'HTTP_X_FORWARDED_FOR' header, if 69 present. Otherwise, `None`. 70 71 Should handle properly configured proxy servers. 72 """ 73 ip_address_list = request.META.get('HTTP_X_FORWARDED_FOR') 74 if ip_address_list: 75 ip_address_list = ip_address_list.split(',') 76 return ip_address_list[0] 77