packc/
component_host_stubs.rs1#![forbid(unsafe_code)]
2
3use anyhow::Result;
4use wasmtime::component::Linker;
5use wasmtime_wasi::p2::add_to_linker_sync;
6use wasmtime_wasi::{ResourceTable, WasiCtx, WasiCtxBuilder, WasiCtxView, WasiView};
7use wasmtime_wasi_http::WasiHttpCtx;
8use wasmtime_wasi_http::p2::{
9 HttpError, HttpResult, WasiHttpCtxView, WasiHttpHooks, WasiHttpView,
10 add_only_http_to_linker_sync,
11};
12use wasmtime_wasi_http::p2::{body, types};
13
14pub struct DescribeHostState {
15 table: ResourceTable,
16 wasi: WasiCtx,
17 wasi_http: WasiHttpCtx,
18 http_hooks: DescribeHttpHooks,
19}
20
21#[derive(Default)]
22struct DescribeHttpHooks;
23
24impl Default for DescribeHostState {
25 fn default() -> Self {
26 let mut wasi = WasiCtxBuilder::new();
29 Self {
30 table: ResourceTable::new(),
31 wasi: wasi.build(),
32 wasi_http: WasiHttpCtx::new(),
33 http_hooks: DescribeHttpHooks,
34 }
35 }
36}
37
38impl WasiHttpHooks for DescribeHttpHooks {
39 fn send_request(
40 &mut self,
41 _request: hyper::Request<body::HyperOutgoingBody>,
42 _config: types::OutgoingRequestConfig,
43 ) -> HttpResult<types::HostFutureIncomingResponse> {
44 Err(HttpError::trap(wasmtime::Error::msg(
45 "wasi:http outgoing requests are unavailable in describe-only host stubs",
46 )))
47 }
48}
49
50impl WasiView for DescribeHostState {
51 fn ctx(&mut self) -> WasiCtxView<'_> {
52 WasiCtxView {
53 table: &mut self.table,
54 ctx: &mut self.wasi,
55 }
56 }
57}
58
59impl WasiHttpView for DescribeHostState {
60 fn http(&mut self) -> WasiHttpCtxView<'_> {
61 WasiHttpCtxView {
62 ctx: &mut self.wasi_http,
63 table: &mut self.table,
64 hooks: &mut self.http_hooks,
65 }
66 }
67}
68
69pub fn add_describe_host_imports(linker: &mut Linker<DescribeHostState>) -> Result<()> {
70 linker.allow_shadowing(true);
73
74 add_to_linker_sync(linker)
75 .map_err(|err| anyhow::anyhow!("register wasi preview2 describe host stubs: {err}"))?;
76
77 add_only_http_to_linker_sync(linker)
78 .map_err(|err| anyhow::anyhow!("register wasi http describe host stubs: {err}"))?;
79
80 Ok(())
87}
88
89pub fn stub_remaining_imports(
96 linker: &mut Linker<DescribeHostState>,
97 component: &wasmtime::component::Component,
98) -> Result<()> {
99 linker
100 .define_unknown_imports_as_traps(component)
101 .map_err(|err| anyhow::anyhow!("stub remaining component imports: {err}"))
102}
103
104#[cfg(test)]
105mod tests {
106 use super::*;
107
108 #[test]
109 fn default_host_state_exposes_wasi_and_http_views() {
110 let mut state = DescribeHostState::default();
111
112 let ctx_view = state.ctx();
113 let _ = ctx_view.table;
114 let _ = ctx_view.ctx;
115
116 let http_view = state.http();
117 let _ = http_view.table;
118 let _ = http_view.ctx;
119 }
120
121 #[test]
122 fn describe_host_imports_register_without_error() {
123 let engine = wasmtime::Engine::default();
124 let mut linker = Linker::new(&engine);
125 add_describe_host_imports(&mut linker).expect("host imports should register");
126 }
127}