首页 > 解决方案 > 如何从 Rust URL 匹配 IP 主机?

问题描述

我正在尝试从以下 URL 获取 IPv4:

use url::{Url, Host};
use std::net::{SocketAddr, IpAddr};

fn main () {
    let url = Url::parse("rtsp://admin:12345@192.168.1.178:10554/tcp/av0_0").unwrap();
    let port = url.port().unwrap_or(554);
    let ip_address = match url.host() {
        Some(Host::Ipv4(ipv4)) => SocketAddr::new(IpAddr::V4(ipv4), port),
        Some(Host::Ipv6(ipv6)) =>  SocketAddr::new(IpAddr::V6(ipv6), port),
        None => panic!("missing host"),
        _ => panic!(format!("only IP hosts are accepted. Your host: {:?}", url.host()))
    };
    println!("{}", ip_address);
}

操场

但它很恐慌:

thread 'main' panicked at 'only IP hosts are accepted. Your host: Some(Domain("192.168.1.178"))', src/main.rs:11:14

怎么了?主机显然是一个IP地址。

标签: urlrust

解决方案


查看错误跟踪器,我发现IP 在 RTSP url 中无法识别

答案显然是url遵循/实现了 URL 标准(这很有意义,因为它是在 Servo 的上下文中开发的),并且 URL 标准只需要对选定数量的方案进行 IPv4 地址识别,因为这些方案(显然)处理IPv4特别地址:https ://github.com/servo/rust-url/issues/577

具体来说:特殊方案是ftp、http、https、ws、wss(也有,file但它是自己的类别),主机表示的差异是:

  • 特殊方案的主机可以是 ipv4、ipv6 或域
  • 非特殊方案的主机可以是 ipv6、不透明、空或 null

url实际上会为非特殊方案解析 ipv6,尽管它只是转储到Some(Domain(...))(或None)中的所有其他内容。

无论如何,这意味着如果您得到Domain结果,您可能想尝试将其解析为 IP。

顺便说一句,您不必format!格式化您的恐慌消息,panic!将在内部进行。


推荐阅读