pub struct LazyConfigAcceptor<IO> {
acceptor: Acceptor,
io: Option<IO>,
alert: Option<(Error, AcceptedAlert)>,
}Expand description
A future for reading a ClientHello from io without committing to a ServerConfig.
Awaiting it yields a StartHandshake, which exposes the
ClientHello (for example, to choose a config based on SNI) and performs
the rest of the handshake via StartHandshake::into_stream().
Fields§
§acceptor: Acceptor§io: Option<IO>§alert: Option<(Error, AcceptedAlert)>Implementations§
Source§impl<IO> LazyConfigAcceptor<IO>
impl<IO> LazyConfigAcceptor<IO>
Sourcepub fn new(acceptor: Acceptor, io: IO) -> Self
pub fn new(acceptor: Acceptor, io: IO) -> Self
Returns a new LazyConfigAcceptor that reads a ClientHello from io.
You likely want to wrap awaiting the acceptor in a timeout to bound how long the
peer may take to send the ClientHello.
Note that awaiting the acceptor is only the first half of the handshake and
StartHandshake::into_stream() performs the rest.
To bound the time for the complete handshake, share one deadline across
both awaits (for example with tokio::time::timeout_at) rather than giving each
its own timeout.
If a timeout elapses before the ClientHello arrives, Self::take_io() can
recover the io, for example to answer the peer in plaintext before closing.
Sourcepub fn take_io(&mut self) -> Option<IO>
pub fn take_io(&mut self) -> Option<IO>
Takes back the client connection. Will return None if called more than once or if the
connection has been accepted.
§Example
use tokio::io::AsyncWriteExt;
let listener = tokio::net::TcpListener::bind("127.0.0.1:4443").await.unwrap();
let (stream, _) = listener.accept().await.unwrap();
let acceptor = tokio_rustls::LazyConfigAcceptor::new(rustls::server::Acceptor::default(), stream);
tokio::pin!(acceptor);
match acceptor.as_mut().await {
Ok(start) => {
let clientHello = start.client_hello();
let config = choose_server_config(clientHello);
let stream = start.into_stream(config).await.unwrap();
// Proceed with handling the ServerConnection...
}
Err(err) => {
if let Some(mut stream) = acceptor.take_io() {
stream
.write_all(
format!("HTTP/1.1 400 Invalid Input\r\n\r\n\r\n{:?}\n", err)
.as_bytes()
)
.await
.unwrap();
}
}
}