aerosocket_server/
tls_transport.rs

1//! TLS transport implementation for WebSocket server
2//!
3//! This module provides TLS/SSL support for secure WebSocket connections.
4//! Note: TLS functionality requires the "tls-transport" feature and proper certificate setup.
5
6#[cfg(feature = "tls-transport")]
7use aerosocket_core::transport::TransportStream;
8#[cfg(feature = "tls-transport")]
9use aerosocket_core::{Error, Result, Transport};
10#[cfg(feature = "tls-transport")]
11use async_trait::async_trait;
12#[cfg(feature = "tls-transport")]
13use std::net::SocketAddr;
14#[cfg(feature = "tls-transport")]
15use std::sync::Arc;
16
17#[cfg(feature = "tls-transport")]
18use tokio::net::{TcpListener, TcpStream as TokioTcpStream};
19#[cfg(feature = "tls-transport")]
20use tokio_rustls::{rustls::ServerConfig as RustlsServerConfig, server::TlsStream, TlsAcceptor};
21
22#[cfg(feature = "tls-transport")]
23/// TLS transport for WebSocket connections
24pub struct TlsTransport {
25    /// TCP listener
26    listener: TcpListener,
27    /// TLS acceptor
28    acceptor: TlsAcceptor,
29    /// Local address
30    local_addr: SocketAddr,
31}
32
33#[cfg(feature = "tls-transport")]
34/// TLS stream wrapper
35pub struct TlsStreamWrapper {
36    inner: TlsStream<TokioTcpStream>,
37}
38
39#[cfg(feature = "tls-transport")]
40#[async_trait]
41impl Transport for TlsTransport {
42    type Stream = TlsStreamWrapper;
43
44    async fn accept(&self) -> Result<Self::Stream> {
45        let tcp_stream = self.listener.accept().await.map_err(|e| Error::Io(e))?.0;
46
47        let tls_stream = self
48            .acceptor
49            .accept(tcp_stream)
50            .await
51            .map_err(|e| Error::Other(format!("Failed to accept TLS connection: {}", e)))?;
52
53        Ok(TlsStreamWrapper { inner: tls_stream })
54    }
55
56    fn local_addr(&self) -> Result<SocketAddr> {
57        Ok(self.local_addr)
58    }
59
60    async fn close(self) -> Result<()> {
61        // The listener will be closed when dropped
62        Ok(())
63    }
64}
65
66#[cfg(feature = "tls-transport")]
67#[async_trait]
68impl TransportStream for TlsStreamWrapper {
69    async fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
70        use tokio::io::AsyncReadExt;
71        self.inner.read(buf).await.map_err(|e| Error::Io(e))
72    }
73
74    async fn write(&mut self, buf: &[u8]) -> Result<usize> {
75        use tokio::io::AsyncWriteExt;
76        self.inner.write(buf).await.map_err(|e| Error::Io(e))
77    }
78
79    async fn write_all(&mut self, buf: &[u8]) -> Result<()> {
80        use tokio::io::AsyncWriteExt;
81        self.inner.write_all(buf).await.map_err(|e| Error::Io(e))
82    }
83
84    async fn flush(&mut self) -> Result<()> {
85        use tokio::io::AsyncWriteExt;
86        self.inner.flush().await.map_err(|e| Error::Io(e))
87    }
88
89    async fn close(&mut self) -> Result<()> {
90        use tokio::io::AsyncWriteExt;
91        self.inner.shutdown().await.map_err(|e| Error::Io(e))
92    }
93
94    fn remote_addr(&self) -> Result<SocketAddr> {
95        self.inner.get_ref().0.peer_addr().map_err(|e| Error::Io(e))
96    }
97
98    fn local_addr(&self) -> Result<SocketAddr> {
99        self.inner
100            .get_ref()
101            .0
102            .local_addr()
103            .map_err(|e| Error::Io(e))
104    }
105}
106
107#[cfg(feature = "tls-transport")]
108impl TlsTransport {
109    /// Bind to the given address with TLS configuration
110    pub async fn bind(addr: SocketAddr, tls_config: RustlsServerConfig) -> Result<Self> {
111        let listener = TcpListener::bind(addr).await.map_err(|e| Error::Io(e))?;
112
113        let local_addr = listener.local_addr().map_err(|e| Error::Io(e))?;
114
115        let acceptor = TlsAcceptor::from(Arc::new(tls_config));
116
117        Ok(Self {
118            listener,
119            acceptor,
120            local_addr,
121        })
122    }
123
124    /// Create a new TLS transport with default configuration
125    pub async fn bind_with_default_config(addr: SocketAddr) -> Result<Self> {
126        let config = create_default_tls_config()?;
127        Self::bind(addr, config).await
128    }
129}
130
131#[cfg(feature = "tls-transport")]
132/// Create a default TLS configuration for testing/development
133pub fn create_default_tls_config() -> Result<RustlsServerConfig> {
134    // For now, return a basic config - in production this should load real certificates
135    Err(Error::Other(
136        "TLS configuration not available in this release. Please implement your own TLS config."
137            .to_string(),
138    ))
139}
140
141#[cfg(not(feature = "tls-transport"))]
142/// TLS transport is not available without the tls-transport feature
143pub struct TlsTransport;
144
145#[cfg(not(feature = "tls-transport"))]
146impl TlsTransport {
147    pub async fn bind(_addr: std::net::SocketAddr, _config: ()) -> aerosocket_core::Result<Self> {
148        Err(aerosocket_core::Error::Other(
149            "TLS transport requires the 'tls-transport' feature to be enabled".to_string(),
150        ))
151    }
152}
153
154#[cfg(test)]
155mod tests {
156    use super::*;
157
158    #[tokio::test]
159    async fn test_tls_transport_creation() {
160        // Simple test to verify TLS transport module compiles
161        // Actual TLS functionality requires certificates
162        // Test passes if this compiles and runs
163    }
164}