Stream: wasmtime

Topic: Help with wasip2 wasi:http/proxy cm-async example


view this post on Zulip Theodore Brockman (Jul 15 2025 at 17:15):

Hey! Hope this is an okay place to ask for some guidance here, I assume there's some dumb mistake I've made somewhere along the line but I haven't had much luck in figuring out what in particular I'm doing wrong, and haven't found a working example for implementing an async HTTP proxy component.

Component is failing to be parsed at TaskCancel:

theo@theo-desktop-black:~/dev/mono/src/apps/wasmtime-wasi-proxy-test-rs$ cargo run -- ../../../target/wasm32-wasip2/release/wasm_test_component.wasm
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.12s
     Running `/home/theo/dev/mono/target/debug/wasmtime-wasi-proxy-test-rs ../../../target/wasm32-wasip2/release/wasm_test_component.wasm`
Error: failed to parse WebAssembly module

Caused by:
    TaskCancel

With this setup (largely just copying wasmtime_wasi_http docs example but with some added config flags enabled in desparation):

#[tokio::main]
async fn main() -> Result<()> {
    let component = std::env::args().nth(1).unwrap();

    // Prepare the `Engine` for Wasmtime
    let mut config = Config::new();
    config.async_support(true);
    config.wasm_component_model(true);
    config.wasm_component_model_async(true);
    let engine = Engine::new(&config)?;

    // Compile the component on the command line to machine code
    let component = Component::from_file(&engine, &component)?; // <-- fails here

With these features and dependencies in my Cargo.toml:

[package]
name = "wasmtime-wasi-proxy-test-rs"
version = "0.1.0"
edition = "2024"

[dependencies]
anyhow = "1"
hyper = { version = "1", features = ["http1", "server"] }
tokio = { version = "1", features = ["full"] }
wasmtime = { version = "34.0.1", features = ["component-model-async", "async", "component-model"] }
wasmtime-wasi = { version = "34.0.1" }
wasmtime-wasi-http = { version = "34.0.1" }
http-body-util = "0.1"
futures-util = "0.3"

For this component:

mod bindings {
    wit_bindgen::generate!({
        world: "wasi:http/proxy",
        async: true,
        generate_all
    });

    use super::Component;
    export!(Component);
}

use bindings::exports::wasi::http::incoming_handler::Guest;
pub use bindings::wasi::http::types::{
    Fields, IncomingRequest, OutgoingBody, OutgoingResponse, ResponseOutparam,
};

struct Component;

impl Guest for Component {
    async fn handle(_request: IncomingRequest, outparam: ResponseOutparam) {
        let hdrs = Fields::new().await;
        let resp = OutgoingResponse::new(hdrs).await;
        let body = resp.body().await.expect("outgoing response");

        ResponseOutparam::set(outparam, Ok(resp)).await;

        let out = body.write().await.expect("outgoing stream");
        out.blocking_write_and_flush(b"Hello, wasi:http/proxy world!\n".to_vec())
            .await
            .expect("writing response");

        drop(out);
        OutgoingBody::finish(body, None).await.unwrap();
    }
}

Built and validated as follows:

theo@theo-desktop-black:~/dev/mono/src/apps/wasm-test-component$ cargo build --target wasm32-wasip2 --release
    Finished `release` profile [optimized] target(s) in 0.06s
theo@theo-desktop-black:~/dev/mono/src/apps/wasm-test-component$ wasm-tools validate ../../../target/wasm32-wasip2/release/wasm_test_component.wasm --features cm-async --verbose
[2025-07-15T17:05:58Z INFO ] read module in 111.89µs
[2025-07-15T17:05:58Z INFO ] module structure validated in 489.511µs
[2025-07-15T17:05:58Z INFO ] functions validated in 1.307049ms

Anything obviously wrong here? I've checked out wasmtime to start digging through code, but if someone can tell me why I'm a dummy (as I'm currently just pattern matching at this point without any real understanding of what I'm doing) and obviate that search it would be greatly appreciated :eyes:

view this post on Zulip Joel Dice (Jul 15 2025 at 17:27):

Hi @Theodore Brockman. The first thing I notice is that the signature of your handle function in the guest component is for wasi:http/incoming-handler@0.2.x, which predates the Component Model async ABI. You'll want to use the 0.3.0-draft version instead, which uses the async ABI.

Here's an example: https://github.com/dicej/hello-wasip3-http. Sorry there's no README.md yet -- I just threw that together yesterday. If you install the latest wasm-tools and then run make in that directory, it should build a component you can run with wasip3-prototyping's version of wasmtime serve. You won't be able to run it on upstream Wasmtime until wasmtime-wasi-http support for p3 is upstreamed from wasip3-prototyping. @Roman Volosatovs is in the process of upstreaming p3 support for both wasmtime-wasi and wasmtime-wasi-http.

Contribute to dicej/hello-wasip3-http development by creating an account on GitHub.

view this post on Zulip Theodore Brockman (Jul 15 2025 at 18:35):

@Joel Dice definitely makes sense why it wouldn't be working then :man_facepalming: thanks for the help and info!


Last updated: Dec 06 2025 at 06:05 UTC