Skip to main content

wasmtime_wasi_tls/providers/
nativetls.rs

1//! The `native_tls` provider.
2
3use crate::{BoxFutureTlsStream, Error, TlsProvider, TlsStream, TlsTransport};
4use std::io;
5use std::pin::{Pin, pin};
6use std::task::Poll;
7
8/// The `native_tls` provider.
9pub struct NativeTlsProvider {
10    _priv: (),
11}
12
13impl TlsProvider for NativeTlsProvider {
14    fn connect(&self, server_name: String, transport: Box<dyn TlsTransport>) -> BoxFutureTlsStream {
15        Box::pin(async move {
16            let connector = native_tls::TlsConnector::new()?;
17            let stream = tokio_native_tls::TlsConnector::from(connector)
18                .connect(&server_name, transport)
19                .await?;
20            Ok(Box::new(NativeTlsStream(stream)) as Box<dyn TlsStream>)
21        })
22    }
23}
24
25impl Default for NativeTlsProvider {
26    fn default() -> Self {
27        Self { _priv: () }
28    }
29}
30
31struct NativeTlsStream(tokio_native_tls::TlsStream<Box<dyn TlsTransport>>);
32
33impl TlsStream for NativeTlsStream {}
34
35impl tokio::io::AsyncRead for NativeTlsStream {
36    fn poll_read(
37        mut self: std::pin::Pin<&mut Self>,
38        cx: &mut std::task::Context<'_>,
39        buf: &mut tokio::io::ReadBuf<'_>,
40    ) -> Poll<io::Result<()>> {
41        pin!(&mut self.as_mut().0).poll_read(cx, buf)
42    }
43}
44
45impl tokio::io::AsyncWrite for NativeTlsStream {
46    fn poll_write(
47        mut self: std::pin::Pin<&mut Self>,
48        cx: &mut std::task::Context<'_>,
49        buf: &[u8],
50    ) -> Poll<io::Result<usize>> {
51        pin!(&mut self.as_mut().0).poll_write(cx, buf)
52    }
53
54    fn poll_flush(
55        mut self: std::pin::Pin<&mut Self>,
56        cx: &mut std::task::Context<'_>,
57    ) -> Poll<Result<(), io::Error>> {
58        pin!(&mut self.as_mut().0).poll_flush(cx)
59    }
60
61    fn poll_shutdown(
62        mut self: std::pin::Pin<&mut Self>,
63        cx: &mut std::task::Context<'_>,
64    ) -> Poll<Result<(), io::Error>> {
65        match pin!(&mut self.as_mut().0).poll_shutdown(cx) {
66            Poll::Ready(Ok(())) => {}
67            Poll::Ready(Err(e)) => return Poll::Ready(Err(e)),
68            Poll::Pending => return Poll::Pending,
69        }
70
71        // `tokio-rustls` & `tokio-openssl` shut down the underlying transport,
72        // but `tokio-native-tls` does not, so we need to do that ourselves:
73        let inner = self.0.get_mut().get_mut().get_mut();
74        Pin::new(inner).poll_shutdown(cx)
75    }
76}
77
78impl From<native_tls::Error> for Error {
79    fn from(e: native_tls::Error) -> Self {
80        Error::msg(e.to_string())
81    }
82}