import ipaddress
import socket
from urllib.parse import urlparse


def safe_public_url(url):
    """Resolve url's host and reject any that maps to a non-public IP (SSRF guard)."""
    p = urlparse(url)
    if p.scheme not in ("http", "https") or not p.hostname:
        raise ValueError("url must be http(s) with a hostname")
    for info in socket.getaddrinfo(p.hostname, None):
        ip = ipaddress.ip_address(info[4][0])
        if (ip.is_private or ip.is_loopback or ip.is_link_local or ip.is_reserved
                or ip.is_multicast or ip.is_unspecified):
            raise ValueError(f"host resolves to non-public ip {ip}")
    return url
