liminal_server/server/connection/websocket/
bound.rs1use std::net::{SocketAddr, TcpListener};
11use std::time::Duration;
12
13use super::AcceptorSettings;
14use crate::ServerError;
15use crate::config::types::WebSocketConfig;
16
17#[cfg(test)]
18#[path = "bound_tests.rs"]
19pub(in crate::server) mod tests;
20
21#[derive(Debug)]
23pub struct BoundWebSocket {
24 pub(super) listener: TcpListener,
25 pub(super) local_addr: SocketAddr,
26 pub(super) settings: AcceptorSettings,
27}
28
29impl BoundWebSocket {
30 pub fn bind(config: &WebSocketConfig) -> Result<Self, ServerError> {
39 let settings = AcceptorSettings {
40 path: config.path.clone(),
41 allowed_origins: config.allowed_origins.clone(),
42 allowed_origin_ports: config.allowed_origin_ports.clone(),
43 ping_interval: config.ping_interval_ms.map(Duration::from_millis),
44 message_bound: super::liminal_ws_message_bound()?,
45 };
46 let listener = TcpListener::bind(config.listen_address).map_err(|source| {
47 ServerError::ListenerBind {
48 address: config.listen_address,
49 source,
50 }
51 })?;
52 let local_addr = listener
56 .local_addr()
57 .map_err(|error| ServerError::ListenerAccept {
58 message: format!("failed to inspect websocket listener address: {error}"),
59 })?;
60 tracing::info!(
61 websocket_listen_address = %local_addr,
62 upgrade_path = %settings.path,
63 allowed_origins = settings.allowed_origins.len(),
64 allowed_origin_ports = settings.allowed_origin_ports.len(),
65 keepalive = ?settings.ping_interval,
66 "liminal websocket listener bound"
67 );
68 Ok(Self {
69 listener,
70 local_addr,
71 settings,
72 })
73 }
74
75 #[must_use]
77 pub const fn local_addr(&self) -> SocketAddr {
78 self.local_addr
79 }
80}