pub(crate) fn strip_port(host: &str) -> &str {
match host.rsplit_once(':') {
Some((name, port)) if !port.is_empty() && port.bytes().all(|b| b.is_ascii_digit()) => name,
_ => host,
}
}
pub(crate) fn is_local_host(host: &str, implicit: bool) -> bool {
let h = host.trim_end_matches('.').to_ascii_lowercase();
let unbracketed = h.trim_start_matches('[').trim_end_matches(']');
if let Ok(ip) = unbracketed.parse::<std::net::IpAddr>() {
return !boatramp_core::access::is_global_ip(ip);
}
implicit && (h == "localhost" || h.ends_with(".localhost") || h.ends_with(".local"))
}
pub(crate) fn parse_deploy_host(host: &str) -> Option<(&str, &str)> {
let (id, after) = host.split_once('.')?;
let site_host = after.strip_prefix("deploy.")?;
if id.is_empty() || site_host.is_empty() || !id.bytes().all(|b| b.is_ascii_hexdigit()) {
return None;
}
Some((id, site_host))
}
#[cfg(test)]
mod tests {
use super::{is_local_host, parse_deploy_host};
#[test]
fn local_hosts_are_exempt_from_verification() {
for h in ["127.0.0.1", "::1", "[::1]", "192.168.1.10", "169.254.0.1"] {
assert!(
is_local_host(h, false),
"{h} should be local (non-global IP)"
);
assert!(
is_local_host(h, true),
"{h} should be local (non-global IP)"
);
}
for h in [
"8.8.8.8", "[2606:4700::1]", "localhost", "blog.localhost", "printer.local", "example.com",
"localhost.evil.com", ] {
assert!(
!is_local_host(h, false),
"{h} must be gated on a public bind"
);
}
for h in ["localhost", "LocalHost", "blog.localhost", "printer.local"] {
assert!(
is_local_host(h, true),
"{h} should be local under implicit routing"
);
}
assert!(!is_local_host("boatramp.dev", true));
}
#[test]
fn parses_preview_host_form() {
assert_eq!(
parse_deploy_host("abc123.deploy.example.com"),
Some(("abc123", "example.com"))
);
assert_eq!(
parse_deploy_host("deadbeef.deploy.staging.example.com"),
Some(("deadbeef", "staging.example.com"))
);
}
#[test]
fn rejects_non_preview_hosts() {
assert_eq!(parse_deploy_host("www.example.com"), None);
assert_eq!(parse_deploy_host("blog.deploy.example.com"), None);
assert_eq!(parse_deploy_host("example.com"), None);
assert_eq!(parse_deploy_host("abc.deploy."), None);
assert_eq!(parse_deploy_host("abc._deploy.example.com"), None);
}
}