1use std::{net::SocketAddr, str::FromStr};
21
22use async_trait::async_trait;
23use url::Url;
24use zenoh_core::zconfigurable;
25use zenoh_link_commons::LocatorInspector;
26use zenoh_protocol::{
27 core::{endpoint::Address, Locator, Metadata, Reliability},
28 transport::BatchSize,
29};
30use zenoh_result::{bail, ZResult};
31mod unicast;
32pub use unicast::*;
33
34const WS_MAX_MTU: BatchSize = BatchSize::MAX;
41
42pub const WS_LOCATOR_PREFIX: &str = "ws";
43
44const IS_RELIABLE: bool = true;
45
46#[derive(Default, Clone, Copy)]
47pub struct WsLocatorInspector;
48#[async_trait]
49impl LocatorInspector for WsLocatorInspector {
50 fn protocol(&self) -> &str {
51 WS_LOCATOR_PREFIX
52 }
53 async fn is_multicast(&self, _locator: &Locator) -> ZResult<bool> {
54 Ok(false)
55 }
56
57 fn is_reliable(&self, locator: &Locator) -> ZResult<bool> {
58 if let Some(reliability) = locator
59 .metadata()
60 .get(Metadata::RELIABILITY)
61 .map(Reliability::from_str)
62 .transpose()?
63 {
64 Ok(reliability == Reliability::Reliable)
65 } else {
66 Ok(IS_RELIABLE)
67 }
68 }
69}
70
71zconfigurable! {
72 static ref WS_DEFAULT_MTU: BatchSize = WS_MAX_MTU;
74 static ref TCP_ACCEPT_THROTTLE_TIME: u64 = 100_000;
77}
78
79pub async fn get_ws_addr(address: Address<'_>) -> ZResult<SocketAddr> {
80 match tokio::net::lookup_host(address.as_str()).await?.next() {
81 Some(addr) => Ok(addr),
82 None => bail!("Couldn't resolve WebSocket locator address: {}", address),
83 }
84}
85
86pub async fn get_ws_url(address: Address<'_>) -> ZResult<Url> {
87 match Url::parse(&format!(
88 "{}://{}",
89 WS_LOCATOR_PREFIX,
90 get_ws_addr(address).await?
91 )) {
92 Ok(url) => Ok(url),
93 Err(e) => bail!(
94 "Couldn't resolve WebSocket locator address: {}: {}",
95 address,
96 e
97 ),
98 }
99}