little-boxes/little_boxes/urlutils.py

55 wiersze
1.3 KiB
Python

import logging
import os
import socket
import ipaddress
from urllib.parse import urlparse
from . import strtobool
from .errors import Error
logger = logging.getLogger(__name__)
class InvalidURLError(Error):
pass
def is_url_valid(url: str) -> bool:
parsed = urlparse(url)
if parsed.scheme not in ["http", "https"]:
return False
# XXX in debug mode, we want to allow requests to localhost to test the federation with local instances
debug_mode = strtobool(os.getenv("MICROBLOGPUB_DEBUG", "false"))
if debug_mode:
return True
if parsed.hostname in ["localhost"]:
return False
try:
ip_address = ipaddress.ip_address(parsed.hostname)
except ValueError:
try:
ip_address = socket.getaddrinfo(parsed.hostname, parsed.port or 80)[0][4][0]
logger.debug(f"dns lookup: {parsed.hostname} -> {ip_address}")
except socket.gaierror:
logger.exception(f"failed to lookup url {url}")
return False
logger.debug(f"{ip_address}")
if ipaddress.ip_address(ip_address).is_private:
logger.info(f"rejecting private URL {url}")
return False
return True
def check_url(url: str) -> None:
logger.debug(f"check_url {url}")
if not is_url_valid(url):
raise InvalidURLError(f'"{url}" is invalid')
return None