pub(crate) fn parse_authority(authority: String) -> Result<http::uri::Authority, ()> {
let has_port = match authority.rfind(']') {
Some(i) => authority[i..].contains(':'),
None => authority.contains(':'),
};
let authority = http::uri::Authority::try_from(authority).map_err(|_| ())?;
if has_port && authority.port_u16().is_none() {
return Err(());
}
Ok(authority)
}
#[cfg(test)]
mod tests {
use super::parse_authority;
#[test]
fn authority_accepts_ipv6_and_validates_ports() {
assert!(parse_authority("example.com".into()).is_ok());
assert!(parse_authority("example.com:443".into()).is_ok());
assert!(parse_authority("127.0.0.1:80".into()).is_ok());
assert!(parse_authority("[::1]".into()).is_ok());
assert!(parse_authority("[2001:db8::1]".into()).is_ok());
assert!(parse_authority("[::1]:443".into()).is_ok());
assert!(parse_authority("example.com:".into()).is_err());
assert!(parse_authority("example.com:abc".into()).is_err());
assert!(parse_authority("example.com:65536".into()).is_err());
assert!(parse_authority("[::1]:abc".into()).is_err());
}
}