This commit is contained in:
Daniel Langbein 2023-03-28 17:08:21 +02:00
parent c2b7f3284b
commit fda4c0f170

View File

@ -93,31 +93,37 @@ def external_ipv4(timeout=5) -> str:
# so we try these endpoints last. # so we try these endpoints last.
endpoints += ['https://ipinfo.io/ip'] endpoints += ['https://ipinfo.io/ip']
for endpoint in endpoints:
backup = None backup = None
try: try:
# Force the usage of IPv4 # Force the usage of IPv4.
# https://stackoverflow.com/a/72440253/6334421 # https://stackoverflow.com/a/72440253/6334421
# #
# Alternatively, use urllib3: https://stackoverflow.com/a/46972341/6334421 # Alternatively, use urllib3: https://stackoverflow.com/a/46972341/6334421
backup = requests.packages.urllib3.util.connection.HAS_IPV6 backup = requests.packages.urllib3.util.connection.HAS_IPV6
requests.packages.urllib3.util.connection.HAS_IPV6 = False requests.packages.urllib3.util.connection.HAS_IPV6 = False
for endpoint in endpoints:
# Timeout after 5 seconds. # Timeout after 5 seconds.
try:
ip = requests.get(endpoint, timeout=timeout).text.strip() ip = requests.get(endpoint, timeout=timeout).text.strip()
except requests.exceptions.RequestException:
continue
# Check if it is actually an IPv4 address. # Check if it is actually an IPv4 address.
# Some services, such as e.g. v4.ident.me, sometimes return IPv6. # Some services, such as e.g. v4.ident.me, sometimes return IPv6.
try:
ipv4 = ipaddress.ip_address(ip) ipv4 = ipaddress.ip_address(ip)
except ValueError:
continue
if not isinstance(ipv4, ipaddress.IPv4Address): if not isinstance(ipv4, ipaddress.IPv4Address):
continue continue
# Return ip address as string. # Return ip address as string.
return ipv4.exploded return ipv4.exploded
except Exception as _e:
continue
finally: finally:
# Allow usage of IPv6 again.
if backup is not None: if backup is not None:
requests.packages.urllib3.util.connection.HAS_IPV6 = backup requests.packages.urllib3.util.connection.HAS_IPV6 = backup
raise Exception('Could not determine public IPv4 address.') raise Exception('Could not determine public IPv4 address.')