monoio_rustls/
server.rs

1use std::sync::Arc;
2
3use monoio::io::{AsyncReadRent, AsyncWriteRent, OwnedReadHalf, OwnedWriteHalf};
4use rustls::{ServerConfig, ServerConnection};
5
6use crate::{stream::Stream, TlsError};
7
8/// A wrapper around an underlying raw stream which implements the TLS protocol.
9pub type TlsStream<IO> = Stream<IO, ServerConnection>;
10/// TlsStream for read only.
11pub type TlsStreamReadHalf<IO> = OwnedReadHalf<TlsStream<IO>>;
12/// TlsStream for write only.
13pub type TlsStreamWriteHalf<IO> = OwnedWriteHalf<TlsStream<IO>>;
14
15/// A wrapper around a `rustls::ServerConfig`, providing an async `accept` method.
16#[derive(Clone)]
17pub struct TlsAcceptor {
18    inner: Arc<ServerConfig>,
19    #[cfg(feature = "unsafe_io")]
20    unsafe_io: bool,
21}
22
23impl From<Arc<ServerConfig>> for TlsAcceptor {
24    fn from(inner: Arc<ServerConfig>) -> TlsAcceptor {
25        TlsAcceptor {
26            inner,
27            #[cfg(feature = "unsafe_io")]
28            unsafe_io: false,
29        }
30    }
31}
32
33impl From<ServerConfig> for TlsAcceptor {
34    fn from(inner: ServerConfig) -> TlsAcceptor {
35        TlsAcceptor {
36            inner: Arc::new(inner),
37            #[cfg(feature = "unsafe_io")]
38            unsafe_io: false,
39        }
40    }
41}
42
43impl TlsAcceptor {
44    /// Enable unsafe-io.
45    /// # Safety
46    /// Users must make sure the buffer ptr and len is valid until io finished.
47    /// So the Future cannot be dropped directly. Consider using CancellableIO.
48    #[cfg(feature = "unsafe_io")]
49    pub unsafe fn unsafe_io(self, enabled: bool) -> Self {
50        Self {
51            unsafe_io: enabled,
52            ..self
53        }
54    }
55
56    pub async fn accept<IO>(&self, stream: IO) -> Result<TlsStream<IO>, TlsError>
57    where
58        IO: AsyncReadRent + AsyncWriteRent,
59    {
60        let session = ServerConnection::new(self.inner.clone())?;
61        #[cfg(feature = "unsafe_io")]
62        let mut stream = if self.unsafe_io {
63            // # Safety
64            // Users already maked unsafe io.
65            unsafe { Stream::new_unsafe(stream, session) }
66        } else {
67            Stream::new(stream, session)
68        };
69        #[cfg(not(feature = "unsafe_io"))]
70        let mut stream = Stream::new(stream, session);
71        stream.handshake().await?;
72        Ok(stream)
73    }
74}