-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Expand file tree
/
Copy pathlib.rs
More file actions
172 lines (155 loc) · 5.33 KB
/
lib.rs
File metadata and controls
172 lines (155 loc) · 5.33 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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
//! # Wasmtime's [wasi-tls] (Transport Layer Security) Implementation
//!
//! This crate provides the Wasmtime host implementation for the [wasi-tls] API.
//! The [wasi-tls] world allows WebAssembly modules to perform SSL/TLS operations,
//! such as establishing secure connections to servers. TLS often relies on other wasi networking systems
//! to provide the stream so it will be common to enable the [wasi:cli] world as well with the networking features enabled.
//!
//! # An example of how to configure [wasi-tls] is the following:
//!
//! ```rust
//! use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView};
//! use wasmtime::{
//! component::{Linker, ResourceTable},
//! Store, Engine, Result, Config
//! };
//! use wasmtime_wasi_tls::{LinkOptions, WasiTls, WasiTlsCtx, WasiTlsCtxBuilder};
//!
//! struct Ctx {
//! table: ResourceTable,
//! wasi_ctx: WasiCtx,
//! wasi_tls_ctx: WasiTlsCtx,
//! }
//!
//! impl WasiView for Ctx {
//! fn ctx(&mut self) -> WasiCtxView<'_> {
//! WasiCtxView { ctx: &mut self.wasi_ctx, table: &mut self.table }
//! }
//! }
//!
//! #[tokio::main]
//! async fn main() -> Result<()> {
//! let ctx = Ctx {
//! table: ResourceTable::new(),
//! wasi_ctx: WasiCtx::builder()
//! .inherit_stderr()
//! .inherit_network()
//! .allow_ip_name_lookup(true)
//! .build(),
//! wasi_tls_ctx: WasiTlsCtxBuilder::new()
//! // Optionally, configure a different TLS provider:
//! // .provider(Box::new(wasmtime_wasi_tls_nativetls::NativeTlsProvider::default()))
//! .build(),
//! };
//!
//! let mut config = Config::new();
//! config.async_support(true);
//! let engine = Engine::new(&config)?;
//!
//! // Set up wasi-cli
//! let mut store = Store::new(&engine, ctx);
//! let mut linker = Linker::new(&engine);
//! wasmtime_wasi::p2::add_to_linker_async(&mut linker)?;
//!
//! // Add wasi-tls types and turn on the feature in linker
//! let mut opts = LinkOptions::default();
//! opts.tls(true);
//! wasmtime_wasi_tls::add_to_linker(&mut linker, &mut opts, |h: &mut Ctx| {
//! WasiTls::new(&h.wasi_tls_ctx, &mut h.table)
//! })?;
//!
//! // ... use `linker` to instantiate within `store` ...
//! Ok(())
//! }
//!
//! ```
//! [wasi-tls]: https://github.com/WebAssembly/wasi-tls
//! [wasi:cli]: https://docs.rs/wasmtime-wasi/latest
#![deny(missing_docs)]
#![doc(test(attr(deny(warnings))))]
#![doc(test(attr(allow(dead_code, unused_variables, unused_mut))))]
use tokio::io::{AsyncRead, AsyncWrite};
use wasmtime::component::{HasData, ResourceTable};
pub mod bindings;
mod host;
mod io;
#[cfg(feature = "p3")]
pub mod p3;
mod rustls;
pub use bindings::types::LinkOptions;
pub use host::{HostClientConnection, HostClientHandshake, HostFutureClientStreams};
pub use rustls::RustlsProvider;
/// Capture the state necessary for use in the `wasi-tls` API implementation.
pub struct WasiTls<'a> {
ctx: &'a WasiTlsCtx,
table: &'a mut ResourceTable,
}
impl<'a> WasiTls<'a> {
/// Create a new Wasi TLS context
pub fn new(ctx: &'a WasiTlsCtx, table: &'a mut ResourceTable) -> Self {
Self { ctx, table }
}
}
/// Add the `wasi-tls` world's types to a [`wasmtime::component::Linker`].
pub fn add_to_linker<T: Send + 'static>(
l: &mut wasmtime::component::Linker<T>,
opts: &mut LinkOptions,
f: fn(&mut T) -> WasiTls<'_>,
) -> anyhow::Result<()> {
bindings::types::add_to_linker::<_, HasWasiTls>(l, &opts, f)?;
Ok(())
}
struct HasWasiTls;
impl HasData for HasWasiTls {
type Data<'a> = WasiTls<'a>;
}
/// Builder-style structure used to create a [`WasiTlsCtx`].
pub struct WasiTlsCtxBuilder {
provider: Box<dyn TlsProvider>,
}
impl WasiTlsCtxBuilder {
/// Creates a builder for a new context with default parameters set.
pub fn new() -> Self {
Default::default()
}
/// Configure the TLS provider to use for this context.
///
/// By default, this is set to the [`RustlsProvider`].
pub fn provider(mut self, provider: Box<dyn TlsProvider>) -> Self {
self.provider = provider;
self
}
/// Uses the configured context so far to construct the final [`WasiTlsCtx`].
pub fn build(self) -> WasiTlsCtx {
WasiTlsCtx {
provider: self.provider,
}
}
}
impl Default for WasiTlsCtxBuilder {
fn default() -> Self {
Self {
provider: Box::new(RustlsProvider::default()),
}
}
}
/// Wasi TLS context needed for internal `wasi-tls` state.
pub struct WasiTlsCtx {
pub(crate) provider: Box<dyn TlsProvider>,
}
/// The data stream that carries the encrypted TLS data.
/// Typically this is a TCP stream.
pub trait TlsTransport: AsyncRead + AsyncWrite + Send + Unpin + 'static {}
impl<T: AsyncRead + AsyncWrite + Send + Unpin + ?Sized + 'static> TlsTransport for T {}
/// A TLS connection.
pub trait TlsStream: AsyncRead + AsyncWrite + Send + Unpin + 'static {}
/// A TLS implementation.
pub trait TlsProvider: Send + Sync + 'static {
/// Set up a client TLS connection using the provided `server_name` and `transport`.
fn connect(
&self,
server_name: String,
transport: Box<dyn TlsTransport>,
) -> BoxFuture<std::io::Result<Box<dyn TlsStream>>>;
}
pub(crate) type BoxFuture<T> = std::pin::Pin<Box<dyn Future<Output = T> + Send>>;