Skip to content

Commit 67a48b2

Browse files
Add opt-in to unstable wasip3 and warn when in use (#3322)
Signed-off-by: Brian Hardock <[email protected]>
1 parent cf3275c commit 67a48b2

File tree

6 files changed

+55
-3
lines changed

6 files changed

+55
-3
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/http/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ serde = { workspace = true }
1616
spin-app = { path = "../app", optional = true }
1717
spin-factor-outbound-http = { path = "../factor-outbound-http" }
1818
spin-http-routes = { path = "../routes" }
19+
terminal = { path = "../terminal" }
1920
tracing = { workspace = true }
2021
wasmtime = { workspace = true }
2122
wasmtime-wasi = { workspace = true }

crates/http/src/config.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ impl HttpTriggerConfig {
3333
///
3434
/// If an executor is not specified, the inferred default is `HttpExecutor::Spin`.
3535
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
36-
#[serde(deny_unknown_fields, rename_all = "lowercase", tag = "type")]
36+
#[serde(deny_unknown_fields, rename_all = "kebab-case", tag = "type")]
3737
pub enum HttpExecutorType {
3838
/// The component implements an HTTP based interface.
3939
///
@@ -43,6 +43,8 @@ pub enum HttpExecutorType {
4343
Http,
4444
/// The component implements the Wagi CGI interface.
4545
Wagi(WagiTriggerConfig),
46+
/// The component implements the WASIp3 HTTP interface (unstable).
47+
Wasip3Unstable,
4648
}
4749

4850
/// Wagi specific configuration for the http executor.

crates/http/src/trigger.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use wasmtime_wasi::p2::bindings::CommandIndices;
66
use wasmtime_wasi_http::bindings::ProxyIndices;
77
use wasmtime_wasi_http::p3::bindings::ProxyIndices as P3ProxyIndices;
88

9+
use crate::config::HttpExecutorType;
10+
911
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
1012
#[serde(deny_unknown_fields)]
1113
pub struct Metadata {
@@ -83,4 +85,45 @@ impl HandlerType {
8385
),
8486
}
8587
}
88+
89+
/// Validate that the [`HandlerType`] is compatible with the [`HttpExecutorType`].
90+
pub fn validate_executor(&self, executor: &Option<HttpExecutorType>) -> anyhow::Result<()> {
91+
match (self, executor) {
92+
(HandlerType::Wasi0_3(_), Some(HttpExecutorType::Wasip3Unstable)) => {
93+
terminal::warn!(
94+
"You’re using wasip3-unstable, an experimental executor for the \
95+
WASI Preview 3 RC interfaces, which will be removed in a future Spin release."
96+
);
97+
Ok(())
98+
}
99+
(HandlerType::Wasi0_3(_), Some(_) | None) => {
100+
anyhow::bail!(
101+
"`{WASI_HTTP_EXPORT_0_3_0_RC_2025_09_16}` is currently unstable and will be \
102+
removed in a future Spin release. You can opt-in to this unstable interface \
103+
by adding `executor = {{ type = \"wasip3-unstable\" }}` to the appropriate \
104+
`[[trigger.http]]` section of your spin.toml file."
105+
);
106+
}
107+
(handler_type, Some(HttpExecutorType::Wasip3Unstable)) => {
108+
anyhow::bail!(
109+
"The wasip3-unstable trigger executor expected a component that \
110+
exports `{WASI_HTTP_EXPORT_0_3_0_RC_2025_09_16}` but found a \
111+
component with type {name}",
112+
name = handler_type.name(),
113+
)
114+
}
115+
(_, _) => Ok(()),
116+
}
117+
}
118+
119+
fn name(&self) -> &str {
120+
match self {
121+
HandlerType::Spin => SPIN_HTTP_EXPORT,
122+
HandlerType::Wasi0_2(_) => WASI_HTTP_EXPORT_0_2_PREFIX,
123+
HandlerType::Wasi0_3(_) => WASI_HTTP_EXPORT_0_3_0_RC_2025_09_16,
124+
HandlerType::Wasi2023_11_10(_) => WASI_HTTP_EXPORT_2023_11_10,
125+
HandlerType::Wasi2023_10_18(_) => WASI_HTTP_EXPORT_2023_10_18,
126+
_ => unreachable!(), // WAGI variant will never appear here
127+
}
128+
}
86129
}

crates/trigger-http/src/server.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,11 @@ impl<F: RuntimeFactors> HttpServer<F> {
151151
) -> anyhow::Result<HandlerType> {
152152
let pre = trigger_app.get_instance_pre(component_id)?;
153153
let handler_type = match executor {
154-
None | Some(HttpExecutorType::Http) => HandlerType::from_instance_pre(pre)?,
154+
None | Some(HttpExecutorType::Http) | Some(HttpExecutorType::Wasip3Unstable) => {
155+
let handler_type = HandlerType::from_instance_pre(pre)?;
156+
handler_type.validate_executor(executor)?;
157+
handler_type
158+
}
155159
Some(HttpExecutorType::Wagi(wagi_config)) => {
156160
anyhow::ensure!(
157161
wagi_config.entrypoint == "_start",
@@ -367,7 +371,7 @@ impl<F: RuntimeFactors> HttpServer<F> {
367371
let executor = executor.as_ref().unwrap_or(&HttpExecutorType::Http);
368372

369373
let res = match executor {
370-
HttpExecutorType::Http => match handler_type {
374+
HttpExecutorType::Http | HttpExecutorType::Wasip3Unstable => match handler_type {
371375
HandlerType::Spin => {
372376
SpinHttpExecutor
373377
.execute(instance_builder, &route_match, req, client_addr)

tests/testcases/wasi-http-p3-streaming/spin.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ version = "1.0.0"
99
[[trigger.http]]
1010
route = "/..."
1111
component = "wasi-http-async"
12+
executor = { type = "wasip3-unstable" }
1213

1314
[component.wasi-http-async]
1415
source = "%{source=integration-wasi-http-p3-streaming}"

0 commit comments

Comments
 (0)