Skip to main content

wasmtime_wasi_tls_nativetls/
lib.rs

1//! The `native_tls` provider.
2
3use std::{io, pin::pin};
4
5use wasmtime_wasi_tls::{TlsProvider, TlsStream, TlsTransport};
6
7type BoxFuture<T> = std::pin::Pin<Box<dyn Future<Output = T> + Send>>;
8
9/// The `native_tls` provider.
10pub struct NativeTlsProvider {
11    _priv: (),
12}
13
14impl TlsProvider for NativeTlsProvider {
15    fn connect(
16        &self,
17        server_name: String,
18        transport: Box<dyn TlsTransport>,
19    ) -> BoxFuture<io::Result<Box<dyn TlsStream>>> {
20        async fn connect_impl(
21            server_name: String,
22            transport: Box<dyn TlsTransport>,
23        ) -> Result<NativeTlsStream, native_tls::Error> {
24            let connector = native_tls::TlsConnector::new()?;
25            let stream = tokio_native_tls::TlsConnector::from(connector)
26                .connect(&server_name, transport)
27                .await?;
28            Ok(NativeTlsStream(stream))
29        }
30
31        Box::pin(async move {
32            let stream = connect_impl(server_name, transport)
33                .await
34                .map_err(|e| io::Error::other(e))?;
35            Ok(Box::new(stream) as Box<dyn TlsStream>)
36        })
37    }
38}
39
40impl Default for NativeTlsProvider {
41    fn default() -> Self {
42        Self { _priv: () }
43    }
44}
45
46struct NativeTlsStream(tokio_native_tls::TlsStream<Box<dyn TlsTransport>>);
47
48impl TlsStream for NativeTlsStream {}
49
50impl tokio::io::AsyncRead for NativeTlsStream {
51    fn poll_read(
52        mut self: std::pin::Pin<&mut Self>,
53        cx: &mut std::task::Context<'_>,
54        buf: &mut tokio::io::ReadBuf<'_>,
55    ) -> std::task::Poll<io::Result<()>> {
56        pin!(&mut self.as_mut().0).poll_read(cx, buf)
57    }
58}
59
60impl tokio::io::AsyncWrite for NativeTlsStream {
61    fn poll_write(
62        mut self: std::pin::Pin<&mut Self>,
63        cx: &mut std::task::Context<'_>,
64        buf: &[u8],
65    ) -> std::task::Poll<io::Result<usize>> {
66        pin!(&mut self.as_mut().0).poll_write(cx, buf)
67    }
68
69    fn poll_flush(
70        mut self: std::pin::Pin<&mut Self>,
71        cx: &mut std::task::Context<'_>,
72    ) -> std::task::Poll<Result<(), io::Error>> {
73        pin!(&mut self.as_mut().0).poll_flush(cx)
74    }
75
76    fn poll_shutdown(
77        mut self: std::pin::Pin<&mut Self>,
78        cx: &mut std::task::Context<'_>,
79    ) -> std::task::Poll<Result<(), io::Error>> {
80        pin!(&mut self.as_mut().0).poll_shutdown(cx)
81    }
82}