|
6 | 6 | //! |
7 | 7 | //! - [x] [mDNS-SD (HTTP)](https://www.w3.org/TR/wot-discovery/#introduction-dns-sd-sec) |
8 | 8 |
|
9 | | -use std::marker::PhantomData; |
| 9 | +use std::{marker::PhantomData, net::IpAddr}; |
10 | 10 |
|
11 | 11 | use futures_core::Stream; |
12 | 12 | use futures_util::StreamExt; |
@@ -43,25 +43,73 @@ pub struct Discoverer<Other: ExtendableThing + ExtendablePiece = Nil> { |
43 | 43 | _other: PhantomData<Other>, |
44 | 44 | } |
45 | 45 |
|
| 46 | +/// Discovered Thing and its mDNS information |
| 47 | +pub struct Discovered<Other: ExtendableThing + ExtendablePiece> { |
| 48 | + /// Discovered Thing |
| 49 | + /// |
| 50 | + /// It is provided as presented by the discovered Servient. |
| 51 | + pub thing: Thing<Other>, |
| 52 | + info: ServiceInfo, |
| 53 | + scheme: String, |
| 54 | +} |
| 55 | + |
| 56 | +impl<Other: ExtendableThing + ExtendablePiece> Discovered<Other> { |
| 57 | + /// Discovered Servient listening addresses |
| 58 | + pub fn get_addresses(&self) -> Vec<IpAddr> { |
| 59 | + self.info |
| 60 | + .get_addresses() |
| 61 | + .iter() |
| 62 | + .map(|ip| ip.to_owned().into()) |
| 63 | + .collect() |
| 64 | + } |
| 65 | + /// Discovered Servient listening port |
| 66 | + pub fn get_port(&self) -> u16 { |
| 67 | + self.info.get_port() |
| 68 | + } |
| 69 | + |
| 70 | + /// Discovered Servient hostname |
| 71 | + /// |
| 72 | + /// To be used to make tls requests |
| 73 | + pub fn get_hostname(&self) -> &str { |
| 74 | + self.info.get_hostname() |
| 75 | + } |
| 76 | + |
| 77 | + /// Discovered Servient scheme |
| 78 | + pub fn get_scheme(&self) -> &str { |
| 79 | + &self.scheme |
| 80 | + } |
| 81 | +} |
| 82 | + |
46 | 83 | async fn get_thing<Other: ExtendableThing + ExtendablePiece>( |
47 | 84 | info: ServiceInfo, |
48 | | -) -> Result<Thing<Other>> { |
| 85 | +) -> Result<Discovered<Other>> { |
49 | 86 | let host = info.get_addresses().iter().next().ok_or(Error::NoAddress)?; |
50 | 87 | let port = info.get_port(); |
51 | 88 | let props = info.get_properties(); |
52 | 89 | let path = props.get_property_val_str("td").unwrap_or(WELL_KNOWN); |
53 | | - let proto = match props.get_property_val_str("tls") { |
54 | | - Some(x) if x == "1" => "https", |
55 | | - _ => "http", |
56 | | - }; |
| 90 | + let proto = props |
| 91 | + .get_property_val_str("scheme") |
| 92 | + .or_else(|| { |
| 93 | + // compatibility with |
| 94 | + props |
| 95 | + .get_property_val_str("tls") |
| 96 | + .map(|tls| if tls == "1" { "https" } else { "http" }) |
| 97 | + }) |
| 98 | + .unwrap_or("http"); |
57 | 99 |
|
58 | 100 | debug!("Got {proto} {host} {port} {path}"); |
59 | 101 |
|
60 | 102 | let r = reqwest::get(format!("{proto}://{host}:{port}{path}")).await?; |
61 | 103 |
|
62 | | - let t = r.json().await?; |
| 104 | + let thing = r.json().await?; |
| 105 | + let scheme = proto.to_owned(); |
| 106 | + let d = Discovered { |
| 107 | + thing, |
| 108 | + info, |
| 109 | + scheme, |
| 110 | + }; |
63 | 111 |
|
64 | | - Ok(t) |
| 112 | + Ok(d) |
65 | 113 | } |
66 | 114 |
|
67 | 115 | impl Discoverer { |
@@ -98,7 +146,7 @@ impl<Other: ExtendableThing + ExtendablePiece> Discoverer<Other> { |
98 | 146 | } |
99 | 147 |
|
100 | 148 | /// Returns an Stream of discovered things |
101 | | - pub fn stream(&self) -> Result<impl Stream<Item = Result<Thing<Other>>>> { |
| 149 | + pub fn stream(&self) -> Result<impl Stream<Item = Result<Discovered<Other>>>> { |
102 | 150 | let receiver = self.mdns.browse(&self.service_type)?; |
103 | 151 |
|
104 | 152 | let s = receiver.into_stream().filter_map(|v| async move { |
|
0 commit comments