Skip to main content

ntex_tls/openssl/
accept.rs

1use std::{fmt, io};
2
3use ntex_io::{Filter, Io, Layer};
4use ntex_service::cfg::Cfg;
5use ntex_service::{Ctx, Service, cfg::Configuration};
6use ntex_util::services::Counter;
7use tls_openssl::ssl;
8
9use crate::{MAX_SSL_ACCEPT_COUNTER, TlsConfig, openssl::SslFilter};
10
11#[derive(Clone)]
12/// Support `TLS` server connections via openssl package
13///
14/// `openssl` feature enables `Acceptor` type
15pub struct SslAcceptor {
16    acceptor: ssl::SslAcceptor,
17    conns: Counter,
18}
19
20impl SslAcceptor {
21    /// Create default openssl acceptor service
22    pub fn new(acceptor: ssl::SslAcceptor) -> Self {
23        MAX_SSL_ACCEPT_COUNTER.with(|conns| SslAcceptor {
24            acceptor,
25            conns: conns.clone(),
26        })
27    }
28}
29
30impl<F: Filter, St> Service<St, Io<F>> for SslAcceptor {
31    type Res = Io<Layer<SslFilter, F>>;
32    type Error = io::Error;
33
34    async fn ready(&self, _: Ctx<'_, Self, St>) -> Result<(), Self::Error> {
35        if !self.conns.is_available() {
36            self.conns.available().await;
37        }
38        Ok(())
39    }
40
41    async fn call(&self, io: Io<F>, _: Ctx<'_, Self, St>) -> Result<Self::Res, Self::Error> {
42        let _guard = self.conns.get();
43        let ssl = ssl::Ssl::new(self.acceptor.context()).map_err(io::Error::other)?;
44        let cfg: Cfg<TlsConfig> = io.cfg().ctx().get();
45
46        log::trace!("{}: Accepting tls connection", io.tag());
47        crate::utils::with_timeout(cfg.handshake_timeout(), super::handshake(io, ssl, true)).await
48    }
49}
50
51impl From<ssl::SslAcceptor> for SslAcceptor {
52    fn from(acceptor: ssl::SslAcceptor) -> Self {
53        Self::new(acceptor)
54    }
55}
56
57impl fmt::Debug for SslAcceptor {
58    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59        f.debug_struct("SslAcceptor").finish()
60    }
61}