aboutsummaryrefslogtreecommitdiff
path: root/webmentions_ssg/url_security.py
diff options
context:
space:
mode:
Diffstat (limited to 'webmentions_ssg/url_security.py')
-rw-r--r--webmentions_ssg/url_security.py28
1 files changed, 15 insertions, 13 deletions
diff --git a/webmentions_ssg/url_security.py b/webmentions_ssg/url_security.py
index ce5d700..51c037a 100644
--- a/webmentions_ssg/url_security.py
+++ b/webmentions_ssg/url_security.py
@@ -9,15 +9,11 @@ class AddressResolutionError(Exception):
pass
-class NonPublicAddressError(Exception):
- pass
-
-
-def ensure_public_url(url: str) -> None:
+def is_public_url(url: str) -> bool:
hostname = urlsplit(url).hostname
if hostname is None:
- raise NonPublicAddressError("URL has no hostname")
+ raise ValueError("No hostname was specified")
try:
answers = dns.resolver.resolve_name(hostname)
@@ -25,13 +21,19 @@ def ensure_public_url(url: str) -> None:
raise AddressResolutionError(
f"Could not resolve hostname {hostname!r}"
) from exc
+ else:
+ for address in answers.addresses():
+ if not ipaddress.ip_address(address).is_global:
+ return False
- addresses = {ipaddress.ip_address(address) for address in answers.addresses()}
+ return True
- if not addresses:
- raise AddressResolutionError(f"Hostname {hostname!r} did not resolve")
- if any(not address.is_global for address in addresses):
- raise NonPublicAddressError(
- f"Hostname {hostname!r} resolves to a non-public address"
- )
+def is_http_url(url: str) -> bool:
+ """Return whether a URL is an absolute HTTP or HTTPS URL."""
+ try:
+ parsed = urlsplit(url)
+ except ValueError:
+ return False
+
+ return parsed.scheme.lower() in {"http", "https"} and parsed.hostname is not None