use anyhow::Context; use std::path::Path; use wasmtime::{Config, Engine, Linker, Module, Store}; use wasmtime_wasi::{sync::WasiCtxBuilder, WasiCtx}; use wasmtime_wasi_http::WasiHttp; use http_body_util::combinators::BoxBody; use http_body_util::BodyExt; use hyper::server::conn::http1; use hyper::{body::Bytes, service::service_fn, Request, Response}; use std::{error::Error, net::SocketAddr}; use tokio::net::TcpListener; async fn test( req: Request, ) -> http::Result>> { let method = req.method().to_string(); Response::builder() .status(http::StatusCode::OK) .header("x-wasmtime-test-method", method) .body(req.into_body().boxed()) } async fn async_run_serve() -> Result<(), Box> { let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); let listener = TcpListener::bind(addr).await?; loop { let (stream, _) = listener.accept().await?; tokio::task::spawn(async move { if let Err(err) = http1::Builder::new() .serve_connection(stream, service_fn(test)) .await { println!("Error serving connection: {:?}", err); } }); } } fn run_server() -> Result<(), Box> { let rt = tokio::runtime::Runtime::new()?; let _ent = rt.enter(); rt.block_on(async_run_serve())?; Ok(()) } pub fn instantiate_inherit_stdio( data: &[u8], bin_name: &str, _workspace: Option<&Path>, ) -> anyhow::Result<()> { let _thread = std::thread::spawn(|| { run_server().unwrap(); }); let config = Config::new(); let engine = Engine::new(&config)?; let module = Module::new(&engine, &data).context("failed to create wasm module")?; let mut linker = Linker::new(&engine); struct Ctx { wasi: WasiCtx, http: WasiHttp, } wasmtime_wasi::sync::add_to_linker(&mut linker, |cx: &mut Ctx| &mut cx.wasi)?; wasmtime_wasi_http::add_to_linker(&mut linker, |cx: &mut Ctx| &mut cx.http)?; // Create our wasi context. let builder = WasiCtxBuilder::new().inherit_stdio().arg(bin_name)?; let mut store = Store::new( &engine, Ctx { wasi: builder.build(), http: WasiHttp::new(), }, ); let instance = linker.instantiate(&mut store, &module)?; let start = instance.get_typed_func::<(), ()>(&mut store, "_start")?; start.call(&mut store, ()) }