utils.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import socket
  2. from . import defaults as defs
  3. def is_valid_ipv4(ip_str):
  4. """
  5. Check the validity of an IPv4 address
  6. """
  7. try:
  8. socket.inet_pton(socket.AF_INET, ip_str)
  9. except AttributeError: # pragma: no cover
  10. try: # Fall-back on legacy API or False
  11. socket.inet_aton(ip_str)
  12. except (AttributeError, socket.error):
  13. return False
  14. return ip_str.count('.') == 3
  15. except socket.error:
  16. return False
  17. return True
  18. def is_valid_ipv6(ip_str):
  19. """
  20. Check the validity of an IPv6 address
  21. """
  22. try:
  23. socket.inet_pton(socket.AF_INET6, ip_str)
  24. except socket.error:
  25. return False
  26. return True
  27. def is_valid_ip(ip_str):
  28. """
  29. Check the validity of an IP address
  30. """
  31. return is_valid_ipv4(ip_str) or is_valid_ipv6(ip_str)
  32. def is_private_ip(ip_str):
  33. """
  34. Returns true of ip_str is private & not routable, else return false
  35. """
  36. return ip_str.startswith(defs.IPWARE_NON_PUBLIC_IP_PREFIX)
  37. def is_public_ip(ip_str):
  38. """
  39. Returns true of ip_str is public & routable, else return false
  40. """
  41. return not is_private_ip(ip_str)
  42. def is_loopback_ip(ip_str):
  43. """
  44. Returns true of ip_str is public & routable, else return false
  45. """
  46. return ip_str.startswith(defs.IPWARE_LOOPBACK_PREFIX)
  47. def get_request_meta(request, key):
  48. """
  49. Given a key, it returns a cleaned up version of the value from request.META, or None
  50. """
  51. value = request.META.get(key, request.META.get(key.replace('_', '-'), '')).strip()
  52. if value == '':
  53. return None
  54. return value
  55. def get_ips_from_string(ip_str):
  56. """
  57. Given a string, it returns a list of one or more valid IP addresses
  58. """
  59. ip_list = []
  60. for ip in ip_str.split(','):
  61. clean_ip = ip.strip().lower()
  62. if clean_ip:
  63. ip_list.append(clean_ip)
  64. ip_count = len(ip_list)
  65. if ip_count > 0:
  66. if is_valid_ip(ip_list[0]) and is_valid_ip(ip_list[-1]):
  67. return ip_list, ip_count
  68. return [], 0
  69. def get_ip_info(ip_str):
  70. """
  71. Given a string, it returns a tuple of (IP, Routable).
  72. """
  73. ip = None
  74. is_routable_ip = False
  75. if is_valid_ip(ip_str):
  76. ip = ip_str
  77. is_routable_ip = is_public_ip(ip)
  78. return ip, is_routable_ip
  79. def get_best_ip(last_ip, next_ip):
  80. """
  81. Given two IP addresses, it returns the the best match ip.
  82. Order of precedence is (Public, Private, Loopback, None)
  83. Right-most IP is returned
  84. """
  85. if last_ip is None:
  86. return next_ip
  87. if is_public_ip(last_ip) and not is_public_ip(next_ip):
  88. return last_ip
  89. if is_private_ip(last_ip) and is_loopback_ip(next_ip):
  90. return last_ip
  91. return next_ip