use super::{RustlsConnection, establish, tls_error};
use crate::tls::TlsConnector;
use ::rustls::{ClientConfig, ClientConnection, pki_types::ServerName};
use base_scheduler::{
Cancellation, OperationResult, SocketClose, SocketStreamReading, SocketStreamWriting,
};
use std::{io, sync::Arc};
#[derive(Clone, Debug)]
pub struct RustlsConnector {
config: Arc<ClientConfig>,
}
impl RustlsConnector {
pub fn new(config: Arc<ClientConfig>) -> Self {
Self { config }
}
}
impl<S> TlsConnector<S, S::Socket> for RustlsConnector
where
S: SocketStreamReading + SocketStreamWriting + SocketClose + ?Sized,
S::Socket: 'static,
{
type Connection = RustlsConnection<S::Socket>;
async fn connect(
&self,
scheduler: &S,
connection: S::Socket,
server_name: &str,
cancellation: &Cancellation,
) -> OperationResult<Self::Connection> {
let state = (|| {
cancellation.check()?;
let name = ServerName::try_from(server_name.to_owned())
.map_err(|error| io::Error::new(io::ErrorKind::InvalidInput, error))?;
Ok(ClientConnection::new(self.config.clone(), name)
.map_err(tls_error)?
.into())
})();
establish(scheduler, connection, state, cancellation).await
}
}