fluvio_async_tls/
acceptor.rs

1use crate::common::tls_state::TlsState;
2use crate::server;
3
4use futures_io::{AsyncRead, AsyncWrite};
5use rustls::{ServerConfig, ServerConnection};
6use std::future::Future;
7use std::io;
8use std::pin::Pin;
9use std::sync::Arc;
10use std::task::{Context, Poll};
11
12/// The TLS accepting part. The acceptor drives
13/// the server side of the TLS handshake process. It works
14/// on any asynchronous stream.
15///
16/// It provides a simple interface (`accept`), returning a future
17/// that will resolve when the handshake process completed. On
18/// success, it will hand you an async `TLSStream`.
19///
20/// ## Example
21///
22/// See /examples/server for an example.
23#[derive(Clone)]
24pub struct TlsAcceptor {
25    inner: Arc<ServerConfig>,
26}
27
28impl TlsAcceptor {
29    /// Accept a client connections. `stream` can be any type implementing `AsyncRead` and `AsyncWrite`,
30    /// such as TcpStreams or Unix domain sockets.
31    ///
32    /// Otherwise, it will return a `Accept` Future, representing the Acceptance part of a
33    /// Tls handshake. It will resolve when the handshake is over.
34    #[inline]
35    pub fn accept<IO>(&self, stream: IO) -> Result<Accept<IO>, rustls::Error>
36    where
37        IO: AsyncRead + AsyncWrite + Unpin,
38    {
39        self.accept_with(stream, |_| ())
40    }
41
42    // Currently private, as exposing ServerSessions exposes rusttls
43    fn accept_with<IO, F>(&self, stream: IO, f: F) -> Result<Accept<IO>, rustls::Error>
44    where
45        IO: AsyncRead + AsyncWrite + Unpin,
46        F: FnOnce(&mut ServerConnection),
47    {
48        let mut session = ServerConnection::new(self.inner.clone())?;
49        f(&mut session);
50
51        Ok(Accept(server::MidHandshake::Handshaking(
52            server::TlsStream {
53                session,
54                io: stream,
55                state: TlsState::Stream,
56            },
57        )))
58    }
59}
60
61/// Future returned from `TlsAcceptor::accept` which will resolve
62/// once the accept handshake has finished.
63pub struct Accept<IO>(server::MidHandshake<IO>);
64
65impl<IO: AsyncRead + AsyncWrite + Unpin> Future for Accept<IO> {
66    type Output = io::Result<server::TlsStream<IO>>;
67
68    #[inline]
69    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
70        Pin::new(&mut self.0).poll(cx)
71    }
72}
73
74impl From<Arc<ServerConfig>> for TlsAcceptor {
75    fn from(inner: Arc<ServerConfig>) -> TlsAcceptor {
76        TlsAcceptor { inner }
77    }
78}
79
80impl From<ServerConfig> for TlsAcceptor {
81    fn from(inner: ServerConfig) -> TlsAcceptor {
82        TlsAcceptor {
83            inner: Arc::new(inner),
84        }
85    }
86}