Skip to content

Commit 4206ff0

Browse files
authored
support wasi:http/[email protected] exports (#2853)
This is needed to support the latest experimental .NET SDK, as well as components produced using e.g. `cargo-component` based on WASI 0.2.1 WIT files. Signed-off-by: Joel Dice <[email protected]>
1 parent dada4d8 commit 4206ff0

File tree

2 files changed

+42
-26
lines changed

2 files changed

+42
-26
lines changed

crates/trigger-http/src/server.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,7 @@ pub enum HandlerType {
478478
pub const WASI_HTTP_EXPORT_2023_10_18: &str = "wasi:http/[email protected]";
479479
pub const WASI_HTTP_EXPORT_2023_11_10: &str = "wasi:http/[email protected]";
480480
pub const WASI_HTTP_EXPORT_0_2_0: &str = "wasi:http/[email protected]";
481+
pub const WASI_HTTP_EXPORT_0_2_1: &str = "wasi:http/[email protected]";
481482

482483
impl HandlerType {
483484
/// Determine the handler type from the exports of a component
@@ -503,7 +504,7 @@ impl HandlerType {
503504
match name {
504505
WASI_HTTP_EXPORT_2023_10_18 => set(HandlerType::Wasi2023_10_18)?,
505506
WASI_HTTP_EXPORT_2023_11_10 => set(HandlerType::Wasi2023_11_10)?,
506-
WASI_HTTP_EXPORT_0_2_0 => set(HandlerType::Wasi0_2)?,
507+
WASI_HTTP_EXPORT_0_2_0 | WASI_HTTP_EXPORT_0_2_1 => set(HandlerType::Wasi0_2)?,
507508
"fermyon:spin/inbound-http" => set(HandlerType::Spin)?,
508509
_ => {}
509510
}
@@ -515,6 +516,7 @@ impl HandlerType {
515516
`{WASI_HTTP_EXPORT_2023_10_18}`, \
516517
`{WASI_HTTP_EXPORT_2023_11_10}`, \
517518
`{WASI_HTTP_EXPORT_0_2_0}`, \
519+
`{WASI_HTTP_EXPORT_0_2_1}`, \
518520
or `fermyon:spin/inbound-http` but it exported none of those"
519521
)
520522
})

crates/trigger-http/src/wasi.rs

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,17 @@ use spin_factors::RuntimeFactors;
1010
use spin_http::routes::RouteMatch;
1111
use tokio::{sync::oneshot, task};
1212
use tracing::{instrument, Instrument, Level};
13-
use wasmtime_wasi_http::{body::HyperIncomingBody as Body, proxy::Proxy, WasiHttpView};
13+
use wasmtime_wasi_http::{
14+
body::HyperIncomingBody as Body,
15+
proxy::exports::wasi::http::incoming_handler::Guest as IncomingHandler, WasiHttpView,
16+
};
1417

1518
use crate::{
1619
headers::prepare_request_headers,
17-
server::{HandlerType, HttpExecutor, WASI_HTTP_EXPORT_2023_10_18, WASI_HTTP_EXPORT_2023_11_10},
20+
server::{
21+
HandlerType, HttpExecutor, WASI_HTTP_EXPORT_0_2_0, WASI_HTTP_EXPORT_0_2_1,
22+
WASI_HTTP_EXPORT_2023_10_18, WASI_HTTP_EXPORT_2023_11_10,
23+
},
1824
TriggerInstanceBuilder,
1925
};
2026

@@ -65,47 +71,55 @@ impl HttpExecutor for WasiHttpExecutor {
6571
drop(wasi_http);
6672

6773
enum Handler {
68-
Latest(Proxy),
74+
Latest(IncomingHandler),
6975
Handler2023_11_10(IncomingHandler2023_11_10),
7076
Handler2023_10_18(IncomingHandler2023_10_18),
7177
}
7278

73-
let handler =
74-
{
75-
let mut exports = instance.exports(&mut store);
76-
match self.handler_type {
77-
HandlerType::Wasi2023_10_18 => {
78-
let mut instance = exports
79+
let handler = {
80+
let mut exports = instance.exports(&mut store);
81+
match self.handler_type {
82+
HandlerType::Wasi2023_10_18 => {
83+
let mut instance =
84+
exports
7985
.instance(WASI_HTTP_EXPORT_2023_10_18)
8086
.ok_or_else(|| {
8187
anyhow!("export of `{WASI_HTTP_EXPORT_2023_10_18}` not an instance")
8288
})?;
83-
Handler::Handler2023_10_18(IncomingHandler2023_10_18::new(&mut instance)?)
84-
}
85-
HandlerType::Wasi2023_11_10 => {
86-
let mut instance = exports
89+
Handler::Handler2023_10_18(IncomingHandler2023_10_18::new(&mut instance)?)
90+
}
91+
HandlerType::Wasi2023_11_10 => {
92+
let mut instance =
93+
exports
8794
.instance(WASI_HTTP_EXPORT_2023_11_10)
8895
.ok_or_else(|| {
8996
anyhow!("export of `{WASI_HTTP_EXPORT_2023_11_10}` not an instance")
9097
})?;
91-
Handler::Handler2023_11_10(IncomingHandler2023_11_10::new(&mut instance)?)
92-
}
93-
HandlerType::Wasi0_2 => {
94-
drop(exports);
95-
Handler::Latest(Proxy::new(&mut store, &instance)?)
96-
}
97-
HandlerType::Spin => unreachable!("should have used SpinHttpExecutor"),
98-
HandlerType::Wagi => unreachable!("should have used WagiExecutor instead"),
98+
Handler::Handler2023_11_10(IncomingHandler2023_11_10::new(&mut instance)?)
99+
}
100+
HandlerType::Wasi0_2 => {
101+
let handler = if let Some(mut export) = exports.instance(WASI_HTTP_EXPORT_0_2_1)
102+
{
103+
IncomingHandler::new(&mut export)
104+
} else if let Some(mut export) = exports.instance(WASI_HTTP_EXPORT_0_2_0) {
105+
IncomingHandler::new(&mut export)
106+
} else {
107+
Err(anyhow!("export of `{WASI_HTTP_EXPORT_0_2_0}` or `{WASI_HTTP_EXPORT_0_2_1}` not an instance"))
108+
}?;
109+
110+
Handler::Latest(handler)
99111
}
100-
};
112+
HandlerType::Spin => unreachable!("should have used SpinHttpExecutor"),
113+
HandlerType::Wagi => unreachable!("should have used WagiExecutor instead"),
114+
}
115+
};
101116

102117
let span = tracing::debug_span!("execute_wasi");
103118
let handle = task::spawn(
104119
async move {
105120
let result = match handler {
106-
Handler::Latest(proxy) => {
107-
proxy
108-
.wasi_http_incoming_handler()
121+
Handler::Latest(handler) => {
122+
handler
109123
.call_handle(&mut store, request, response)
110124
.instrument(span)
111125
.await

0 commit comments

Comments
 (0)