diff --git a/Cargo.lock b/Cargo.lock index f524fe1..6fe9901 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1616,9 +1616,9 @@ dependencies = [ "futures", "httparse", "network-interface", + "quick-xml", "reqwest", "serde", - "serde-xml-rs", "tokio", "tracing", "tracing-subscriber", @@ -2649,18 +2649,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-xml-rs" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb3aa78ecda1ebc9ec9847d5d3aba7d618823446a049ba2491940506da6e2782" -dependencies = [ - "log", - "serde", - "thiserror", - "xml-rs", -] - [[package]] name = "serde_derive" version = "1.0.209" @@ -3932,12 +3920,6 @@ dependencies = [ "tap", ] -[[package]] -name = "xml-rs" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "539a77ee7c0de333dcc6da69b177380a0b81e0dacfa4f7344c465a36871ee601" - [[package]] name = "zerocopy" version = "0.7.35" diff --git a/crates/upnp/Cargo.toml b/crates/upnp/Cargo.toml index a4359ee..94762d5 100644 --- a/crates/upnp/Cargo.toml +++ b/crates/upnp/Cargo.toml @@ -16,13 +16,13 @@ tracing = "0.1" anyhow = "1" reqwest = { version = "0.12", default-features = false } serde = { version = "1", features = ["derive"] } -serde-xml-rs = "0.6.0" tokio = { version = "1", features = ["macros"] } futures = "0.3" url = "2" network-interface = { version = "2" } httparse = "1.9.4" bstr = "1.10.0" +quick-xml = { version = "0.36.1", features = ["serialize"] } [dev-dependencies] tokio = { version = "1", features = ["macros", "rt-multi-thread"] } diff --git a/crates/upnp/src/lib.rs b/crates/upnp/src/lib.rs index 5c0d6e1..ac68c92 100644 --- a/crates/upnp/src/lib.rs +++ b/crates/upnp/src/lib.rs @@ -4,7 +4,6 @@ use futures::{stream::FuturesUnordered, StreamExt, TryFutureExt}; use network_interface::NetworkInterfaceConfig; use reqwest::Client; use serde::Deserialize; -use serde_xml_rs::from_str; use std::{ collections::HashSet, net::{Ipv4Addr, SocketAddr, SocketAddrV4}, @@ -115,19 +114,19 @@ async fn forward_port( Ok(()) } -#[derive(Clone, Debug, Deserialize)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq)] struct RootDesc { #[serde(rename = "device")] devices: Vec, } -#[derive(Default, Clone, Debug, Deserialize)] +#[derive(Default, Clone, Debug, Deserialize, PartialEq, Eq)] pub struct DeviceList { #[serde(rename = "device")] devices: Vec, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Deserialize, PartialEq, Eq)] pub struct Device { #[serde(rename = "deviceType")] pub device_type: String, @@ -169,13 +168,13 @@ impl Device { } } -#[derive(Clone, Debug, Deserialize, Default)] +#[derive(Clone, Debug, Deserialize, Default, PartialEq, Eq)] pub struct ServiceList { #[serde(rename = "service", default)] pub services: Vec, } -#[derive(Clone, Debug, Deserialize)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq)] pub struct Service { #[serde(rename = "serviceType")] pub service_type: String, @@ -256,7 +255,7 @@ async fn discover_services(location: Url) -> anyhow::Result { .await .context("failed to read response body")?; trace!("received from {location}: {response}"); - let root_desc: RootDesc = from_str(&response) + let root_desc: RootDesc = quick_xml::de::from_str(&response) .context("failed to parse response body as xml") .map_err(|e| { debug!("failed to parse this XML: {response}"); @@ -476,12 +475,56 @@ impl UpnpPortForwarder { #[cfg(test)] mod tests { - use serde_xml_rs::from_str; + use quick_xml::de::from_str; - use crate::RootDesc; + use crate::{Device, DeviceList, RootDesc, Service, ServiceList}; #[test] fn test_parse() { - dbg!(from_str::(include_str!("resources/test/devices-0.xml")).unwrap()); + let actual = from_str::(include_str!("resources/test/devices-0.xml")).unwrap(); + let expected = RootDesc { + devices: vec![Device { + device_type: "urn:schemas-upnp-org:device:InternetGatewayDevice:1".into(), + friendly_name: "ARRIS TG3492LG".into(), + service_list: ServiceList { + services: vec![Service { + service_type: "urn:schemas-upnp-org:service:Layer3Forwarding:1".into(), + control_url: "/upnp/control/Layer3Forwarding".into(), + scpd_url: "/Layer3ForwardingSCPD.xml".into(), + }], + }, + device_list: DeviceList { + devices: vec![Device { + device_type: "urn:schemas-upnp-org:device:WANDevice:1".into(), + friendly_name: "WANDevice:1".into(), + service_list: ServiceList { + services: vec![Service { + service_type: + "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1".into(), + control_url: "/upnp/control/WANCommonInterfaceConfig0".into(), + scpd_url: "/WANCommonInterfaceConfigSCPD.xml".into(), + }], + }, + device_list: DeviceList { + devices: vec![Device { + device_type: "urn:schemas-upnp-org:device:WANConnectionDevice:1" + .into(), + friendly_name: "WANConnectionDevice:1".into(), + service_list: ServiceList { + services: vec![Service { + service_type: + "urn:schemas-upnp-org:service:WANIPConnection:1".into(), + control_url: "/upnp/control/WANIPConnection0".into(), + scpd_url: "/WANIPConnectionServiceSCPD.xml".into(), + }], + }, + device_list: DeviceList { devices: vec![] }, + }], + }, + }], + }, + }], + }; + assert_eq!(actual, expected); } } diff --git a/desktop/src-tauri/Cargo.lock b/desktop/src-tauri/Cargo.lock index 3b2c346..4855d4e 100644 --- a/desktop/src-tauri/Cargo.lock +++ b/desktop/src-tauri/Cargo.lock @@ -2012,9 +2012,9 @@ dependencies = [ "futures", "httparse", "network-interface", + "quick-xml 0.36.1", "reqwest", "serde", - "serde-xml-rs", "tokio", "tracing", "url", @@ -3211,18 +3211,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-xml-rs" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb3aa78ecda1ebc9ec9847d5d3aba7d618823446a049ba2491940506da6e2782" -dependencies = [ - "log", - "serde", - "thiserror", - "xml-rs", -] - [[package]] name = "serde_derive" version = "1.0.209" @@ -5011,12 +4999,6 @@ dependencies = [ "rustix", ] -[[package]] -name = "xml-rs" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "539a77ee7c0de333dcc6da69b177380a0b81e0dacfa4f7344c465a36871ee601" - [[package]] name = "zerocopy" version = "0.7.35"