forked from compio-rs/compio
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrtls.rs
More file actions
70 lines (60 loc) · 2.2 KB
/
rtls.rs
File metadata and controls
70 lines (60 loc) · 2.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use std::{
io,
pin::Pin,
sync::Arc,
task::{Context, Poll},
};
use compio_io::{AsyncRead, AsyncWrite, compat::AsyncStream};
use futures_util::FutureExt;
use rustls::{
ServerConfig, ServerConnection,
server::{Acceptor, ClientHello},
};
use crate::TlsStream;
/// A lazy TLS acceptor that performs the initial handshake and allows access to
/// the [`ClientHello`] message before completing the handshake.
pub struct LazyConfigAcceptor<S>(futures_rustls::LazyConfigAcceptor<Pin<Box<AsyncStream<S>>>>);
impl<S: AsyncRead + AsyncWrite + Unpin + 'static> LazyConfigAcceptor<S> {
/// Create a new [`LazyConfigAcceptor`] with the given acceptor and stream.
pub fn new(acceptor: Acceptor, s: S) -> Self {
Self(futures_rustls::LazyConfigAcceptor::new(
acceptor,
Box::pin(AsyncStream::new(s)),
))
}
}
impl<S: AsyncRead + AsyncWrite + Unpin + 'static> Future for LazyConfigAcceptor<S> {
type Output = Result<StartHandshake<S>, io::Error>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
self.0.poll_unpin(cx).map_ok(StartHandshake)
}
}
/// A TLS acceptor that has completed the initial handshake and allows access to
/// the [`ClientHello`] message.
pub struct StartHandshake<S>(futures_rustls::StartHandshake<Pin<Box<AsyncStream<S>>>>);
impl<S: AsyncRead + AsyncWrite + Unpin + 'static> StartHandshake<S> {
/// Get the [`ClientHello`] message from the initial handshake.
pub fn client_hello(&self) -> ClientHello<'_> {
self.0.client_hello()
}
/// Complete the TLS handshake and return a [`TlsStream`] if successful.
pub fn into_stream(
self,
config: Arc<ServerConfig>,
) -> impl Future<Output = io::Result<TlsStream<S>>> {
self.into_stream_with(config, |_| ())
}
/// Complete the TLS handshake and return a [`TlsStream`] if successful.
pub fn into_stream_with<F>(
self,
config: Arc<ServerConfig>,
f: F,
) -> impl Future<Output = io::Result<TlsStream<S>>>
where
F: FnOnce(&mut ServerConnection),
{
self.0
.into_stream_with(config, f)
.map(|res| res.map(TlsStream::from))
}
}