|
@@ -78,24 +78,59 @@ if BEHIND_REVERSE_PROXY:
|
|
|
log.debug('Axes is configured to be behind reverse proxy')
|
|
log.debug('Axes is configured to be behind reverse proxy')
|
|
|
log.debug('Looking for header value %s', REVERSE_PROXY_HEADER)
|
|
log.debug('Looking for header value %s', REVERSE_PROXY_HEADER)
|
|
|
|
|
|
|
|
|
|
+def is_valid_ip(ip_address):
|
|
|
|
|
+ """ Check Validity of an IP address """
|
|
|
|
|
+ valid = True
|
|
|
|
|
+ try:
|
|
|
|
|
+ socket.inet_aton(ip_address.strip())
|
|
|
|
|
+ except:
|
|
|
|
|
+ valid = False
|
|
|
|
|
+ return valid
|
|
|
|
|
+
|
|
|
|
|
+def get_ip_address_from_request(request):
|
|
|
|
|
+ """ Makes the best attempt to get the client's real IP or return the loopback """
|
|
|
|
|
+ PRIVATE_IPS_PREFIX = ('10.', '172.', '192.', '127.')
|
|
|
|
|
+ ip_address = ''
|
|
|
|
|
+ x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR', '')
|
|
|
|
|
+ if x_forwarded_for and ',' not in x_forwarded_for:
|
|
|
|
|
+ # Hue's LB can be hosted on Private IP address.
|
|
|
|
|
+ if is_valid_ip(x_forwarded_for):
|
|
|
|
|
+ ip_address = x_forwarded_for.strip()
|
|
|
|
|
+ elif x_forwarded_for and ',' in x_forwarded_for:
|
|
|
|
|
+ # Hue Server may have more than one reverse proxy in front of it.
|
|
|
|
|
+ x_forwarded_for_first_ip = x_forwarded_for.split(',')[0]
|
|
|
|
|
+ if is_valid_ip(x_forwarded_for_first_ip):
|
|
|
|
|
+ ip_address = x_forwarded_for_first_ip.strip()
|
|
|
|
|
+ else:
|
|
|
|
|
+ ips = [ip.strip() for ip in x_forwarded_for.split(',')]
|
|
|
|
|
+ for ip in ips:
|
|
|
|
|
+ if ip.startswith(PRIVATE_IPS_PREFIX):
|
|
|
|
|
+ continue
|
|
|
|
|
+ elif not is_valid_ip(ip):
|
|
|
|
|
+ continue
|
|
|
|
|
+ else:
|
|
|
|
|
+ ip_address = ip
|
|
|
|
|
+ break
|
|
|
|
|
+ if not ip_address:
|
|
|
|
|
+ x_real_ip = request.META.get('HTTP_X_REAL_IP', '')
|
|
|
|
|
+ if x_real_ip:
|
|
|
|
|
+ if not x_real_ip.startswith(PRIVATE_IPS_PREFIX) and is_valid_ip(x_real_ip):
|
|
|
|
|
+ ip_address = x_real_ip.strip()
|
|
|
|
|
+ if not ip_address:
|
|
|
|
|
+ remote_addr = request.META.get('REMOTE_ADDR', '')
|
|
|
|
|
+ if remote_addr:
|
|
|
|
|
+ if not remote_addr.startswith(PRIVATE_IPS_PREFIX) and is_valid_ip(remote_addr):
|
|
|
|
|
+ ip_address = remote_addr.strip()
|
|
|
|
|
+ if remote_addr.startswith(PRIVATE_IPS_PREFIX) and is_valid_ip(remote_addr):
|
|
|
|
|
+ ip_address = remote_addr.strip()
|
|
|
|
|
+ if not ip_address:
|
|
|
|
|
+ ip_address = '127.0.0.1'
|
|
|
|
|
+ return ip_address
|
|
|
|
|
|
|
|
def get_ip(request):
|
|
def get_ip(request):
|
|
|
- ip = request.META.get('REMOTE_ADDR', '')
|
|
|
|
|
-
|
|
|
|
|
- if BEHIND_REVERSE_PROXY:
|
|
|
|
|
- ip = request.META.get(REVERSE_PROXY_HEADER, '').split(',', 1)[0]
|
|
|
|
|
- ip = ip.strip()
|
|
|
|
|
- if not ip:
|
|
|
|
|
- raise Warning(
|
|
|
|
|
- 'Axes is configured for operation behind a reverse proxy '
|
|
|
|
|
- 'but could not find an HTTP header value. Check your proxy '
|
|
|
|
|
- 'server settings to make sure this header value is being '
|
|
|
|
|
- 'passed. Header value {0}'.format(REVERSE_PROXY_HEADER)
|
|
|
|
|
- )
|
|
|
|
|
-
|
|
|
|
|
|
|
+ ip = get_ip_address_from_request(request)
|
|
|
return ip
|
|
return ip
|
|
|
|
|
|
|
|
-
|
|
|
|
|
def query2str(items, max_length=1024):
|
|
def query2str(items, max_length=1024):
|
|
|
"""Turns a dictionary into an easy-to-read list of key-value pairs.
|
|
"""Turns a dictionary into an easy-to-read list of key-value pairs.
|
|
|
|
|
|