ruddarr / app

A native iOS companion app for Radarr and Sonarr instances.
https://apps.apple.com/app/ruddarr/id6476240130
MIT License
98 stars 6 forks source link

Improve error handling for private URLs #129

Closed tillkruss closed 8 months ago

tillkruss commented 8 months ago

https://softwareengineering.stackexchange.com/questions/384960/is-my-algorithm-for-determining-whether-a-ipv4-is-public-or-private-correct

tillkruss commented 8 months ago

Testing whether a URL corresponds to a local IP address (such as 127.0.0.1 or addresses within the 10.x.x.x, 172.16.x.x to 172.31.x.x, and 192.168.x.x ranges) can be achieved by parsing the URL and examining its host component. This process involves:

  1. Parsing the URL to extract the hostname.
  2. Determining if the hostname is a special loopback address (127.0.0.1 or localhost) or falls within private IP address ranges.

Here's a simple example in Python demonstrating how to check if a given URL is local:

from ipaddress import ip_address, ip_network
from urllib.parse import urlparse

def is_local_url(url):
    try:
        parsed_url = urlparse(url)
        host = parsed_url.hostname

        # Check if host is a local IP address (127.0.0.1 or localhost)
        if host in ["localhost", "127.0.0.1"]:
            return True

        # Convert the hostname to an IP address (assumes IPv4 for simplicity)
        ip = ip_address(host)

        # Define private IP address ranges
        private_networks = [
            ip_network("10.0.0.0/8"),
            ip_network("172.16.0.0/12"),
            ip_network("192.168.0.0/16"),
            ip_network("127.0.0.0/8")  # Including the loopback range for completeness
        ]

        # Check if the IP address falls within any of the private ranges
        return any(ip in network for network in private_networks)
    except ValueError:
        # Handle invalid IP addresses
        return False

# Example usage
url = "http://127.0.0.1/path"
print(is_local_url(url))  # True

url = "http://192.168.1.1/path"
print(is_local_url(url))  # True

url = "http://example.com/path"
print(is_local_url(url))  # False

Key Points:

tillkruss commented 8 months ago
Pattern           Class        Remark 
10.xxx.xxx.xxx      A 
172.YYY.xxx.xxx     B          YYY is between 16 and 31 included
192.168.xxx.xxx     C