use crate::error::Result;
use crate::util::ssrf;
use url::Url;
pub fn validate_url(url_str: &str) -> Result<Url> {
ssrf::validate_url(url_str)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_valid_http_url() {
assert!(validate_url("http://example.com/feed.xml").is_ok());
}
#[test]
fn test_valid_https_url() {
assert!(validate_url("https://blog.example.org/rss").is_ok());
}
#[test]
fn test_valid_with_port() {
assert!(validate_url("https://example.com:8443/feed").is_ok());
}
#[test]
fn test_valid_with_path() {
assert!(validate_url("https://example.com/path/to/feed.xml").is_ok());
}
#[test]
fn test_reject_file_scheme() {
assert!(validate_url("file:///etc/passwd").is_err());
}
#[test]
fn test_reject_ftp_scheme() {
assert!(validate_url("ftp://example.com/file").is_err());
}
#[test]
fn test_reject_javascript_scheme() {
assert!(validate_url("javascript:alert(1)").is_err());
}
#[test]
fn test_reject_data_scheme() {
assert!(validate_url("data:text/html,<script>alert(1)</script>").is_err());
}
#[test]
fn test_reject_ipv4_private_10() {
assert!(validate_url("http://10.0.0.1/").is_err());
assert!(validate_url("http://10.255.255.255/").is_err());
}
#[test]
fn test_reject_ipv4_private_172() {
assert!(validate_url("http://172.16.0.1/").is_err());
assert!(validate_url("http://172.31.255.255/").is_err());
}
#[test]
fn test_reject_ipv4_private_192() {
assert!(validate_url("http://192.168.0.1/").is_err());
assert!(validate_url("http://192.168.255.255/").is_err());
}
#[test]
fn test_reject_ipv4_localhost() {
assert!(validate_url("http://127.0.0.1/").is_err());
assert!(validate_url("http://127.0.0.2/").is_err());
}
#[test]
fn test_reject_ipv4_link_local() {
assert!(validate_url("http://169.254.169.254/").is_err());
assert!(validate_url("http://169.254.0.1/").is_err());
}
#[test]
fn test_reject_ipv4_zero() {
assert!(validate_url("http://0.0.0.0/").is_err());
}
#[test]
fn test_reject_ipv4_broadcast() {
assert!(validate_url("http://255.255.255.255/").is_err());
}
#[test]
fn test_reject_ipv6_loopback() {
assert!(validate_url("http://[::1]/").is_err());
}
#[test]
fn test_reject_ipv6_link_local() {
assert!(validate_url("http://[fe80::1]/").is_err());
}
#[test]
fn test_reject_ipv6_unique_local() {
assert!(validate_url("http://[fc00::1]/").is_err());
assert!(validate_url("http://[fd00::1]/").is_err());
}
#[test]
fn test_reject_localhost_domain() {
assert!(validate_url("http://localhost/").is_err());
}
#[test]
fn test_reject_local_tld() {
assert!(validate_url("http://myserver.local/").is_err());
}
#[test]
fn test_reject_internal_tld() {
assert!(validate_url("http://server.internal/").is_err());
}
#[test]
fn test_reject_cloud_metadata() {
assert!(validate_url("http://metadata.google.internal/").is_err());
assert!(validate_url("http://metadata.azure.com/").is_err());
}
#[test]
fn test_reject_no_host() {
assert!(validate_url("http://").is_err());
}
#[test]
fn test_reject_invalid_url() {
assert!(validate_url("not a url").is_err());
}
#[test]
fn test_public_ip_allowed() {
assert!(validate_url("http://8.8.8.8/").is_ok());
assert!(validate_url("http://1.1.1.1/").is_ok());
}
#[test]
fn test_carrier_grade_nat_blocked() {
assert!(validate_url("http://100.64.0.1/").is_err());
assert!(validate_url("http://100.127.255.255/").is_err());
}
#[test]
fn test_ipv6_multicast_blocked() {
assert!(validate_url("http://[ff00::1]/").is_err());
assert!(validate_url("http://[ff02::1]/").is_err());
}
}