+81
-43
src/parser.rs
+81
-43
src/parser.rs
···
96
96
let device = root
97
97
.find("{urn:schemas-upnp-org:device-1-0}device")
98
98
.unwrap();
99
-
let service_list = device.find("{urn:schemas-upnp-org:device-1-0}serviceList");
100
-
let services = service_list.unwrap().children();
101
99
102
-
let services: Vec<Service> = services
103
-
.into_iter()
104
-
.map(|item| Service {
105
-
service_type: item
106
-
.find("{urn:schemas-upnp-org:device-1-0}serviceType")
107
-
.unwrap()
108
-
.text()
109
-
.to_string(),
110
-
service_id: item
111
-
.find("{urn:schemas-upnp-org:device-1-0}serviceId")
112
-
.unwrap()
113
-
.text()
114
-
.to_string(),
115
-
control_url: item
116
-
.find("{urn:schemas-upnp-org:device-1-0}controlURL")
117
-
.unwrap()
118
-
.text()
119
-
.to_string(),
120
-
event_sub_url: item
121
-
.find("{urn:schemas-upnp-org:device-1-0}eventSubURL")
122
-
.unwrap()
123
-
.text()
124
-
.to_string(),
125
-
scpd_url: item
126
-
.find("{urn:schemas-upnp-org:device-1-0}SCPDURL")
127
-
.unwrap()
128
-
.text()
129
-
.to_string(),
130
-
actions: vec![],
131
-
})
132
-
.map(|mut service| {
133
-
service.control_url = build_absolute_url(base_url, &service.control_url);
134
-
service.event_sub_url = build_absolute_url(base_url, &service.event_sub_url);
135
-
service.scpd_url = build_absolute_url(base_url, &service.scpd_url);
136
-
service
137
-
})
138
-
.collect();
139
100
let mut services_with_actions: Vec<Service> = vec![];
140
-
for service in &services {
141
-
let mut service = service.clone();
142
-
service.actions = parse_service_description(&service.scpd_url).await;
143
-
services_with_actions.push(service);
101
+
if let Some(service_list) = device.find("{urn:schemas-upnp-org:device-1-0}serviceList") {
102
+
let services = service_list.children();
103
+
104
+
let services: Vec<Service> = services
105
+
.into_iter()
106
+
.map(|item| Service {
107
+
service_type: item
108
+
.find("{urn:schemas-upnp-org:device-1-0}serviceType")
109
+
.unwrap()
110
+
.text()
111
+
.to_string(),
112
+
service_id: item
113
+
.find("{urn:schemas-upnp-org:device-1-0}serviceId")
114
+
.unwrap()
115
+
.text()
116
+
.to_string(),
117
+
control_url: item
118
+
.find("{urn:schemas-upnp-org:device-1-0}controlURL")
119
+
.unwrap()
120
+
.text()
121
+
.to_string(),
122
+
event_sub_url: item
123
+
.find("{urn:schemas-upnp-org:device-1-0}eventSubURL")
124
+
.unwrap()
125
+
.text()
126
+
.to_string(),
127
+
scpd_url: item
128
+
.find("{urn:schemas-upnp-org:device-1-0}SCPDURL")
129
+
.unwrap()
130
+
.text()
131
+
.to_string(),
132
+
actions: vec![],
133
+
})
134
+
.map(|mut service| {
135
+
service.control_url = build_absolute_url(base_url, &service.control_url);
136
+
service.event_sub_url = build_absolute_url(base_url, &service.event_sub_url);
137
+
service.scpd_url = build_absolute_url(base_url, &service.scpd_url);
138
+
service
139
+
})
140
+
.collect();
141
+
142
+
for service in &services {
143
+
let mut service = service.clone();
144
+
service.actions = parse_service_description(&service.scpd_url).await;
145
+
services_with_actions.push(service);
146
+
}
144
147
}
148
+
145
149
services_with_actions
146
150
}
147
151
···
755
759
}
756
760
Ok(transport_info)
757
761
}
762
+
763
+
#[cfg(test)]
764
+
mod tests {
765
+
use crate::parser::parse_services;
766
+
767
+
#[tokio::test]
768
+
async fn test_parsing_device_without_service_list() {
769
+
const XML_ROOT: &'static str = r#"<?xml version="1.0" encoding="UTF-8"?>
770
+
<root xmlns="urn:schemas-upnp-org:device-1-0">
771
+
<specVersion>
772
+
<major>1</major>
773
+
<minor>0</minor>
774
+
</specVersion>
775
+
<device>
776
+
<deviceType>urn:schemas-upnp-org:device:WLANAccessPointDevice:1</deviceType>
777
+
<friendlyName>NETGEAR47B64C</friendlyName>
778
+
<manufacturer>NETGEAR</manufacturer>
779
+
<manufacturerURL>https://www.netgear.com</manufacturerURL>
780
+
<modelDescription>NETGEAR Dual Band Access Point</modelDescription>
781
+
<modelName>WAX214</modelName>
782
+
<modelNumber>WAX214</modelNumber>
783
+
<modelURL>https://www.netgear.com</modelURL>
784
+
<firmwareVersion>2.1.1.3</firmwareVersion>
785
+
<insightMode>0</insightMode>
786
+
<serialNumber>XXXXXXXXX</serialNumber>
787
+
<UDN>uuid:919ba4ec-ec93-490f-b0e3-80CC9C47B64C</UDN>
788
+
<presentationURL>http://xxxxxx:1337/</presentationURL>
789
+
</device>
790
+
</root>"#;
791
+
792
+
let result = parse_services("http://xxxxxx:1337/", XML_ROOT).await;
793
+
assert_eq!(result.len(), 0);
794
+
}
795
+
}