diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index af03aca..0f73ed8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -75,6 +75,9 @@ jobs: - run: cargo build --no-default-features -p ${{ matrix.crate }} --target wasm32-wasip1 - run: cargo build --no-default-features -p ${{ matrix.crate }} --target wasm32-wasip2 + - run: cargo build --no-default-features -p ${{ matrix.crate }} --features std + - run: cargo build --no-default-features -p ${{ matrix.crate }} --all-features + - run: cargo test -p ${{ matrix.crate }} --doc generate: @@ -94,7 +97,7 @@ jobs: ./ci/vendor-wit.sh git diff --exit-code - run: | - version=0.54.0 + version=0.57.0 mkdir wit-bindgen cd wit-bindgen diff --git a/Cargo.toml b/Cargo.toml index f86dd77..38f3c03 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ rust-version = "1.87.0" [workspace.dependencies] rand = { version = "0.8.5", default-features = false } wasi = { version = "0.14.6", path = ".", default-features = false } -wit-bindgen = { version = "0.54.0", default-features = false } +wit-bindgen = { version = "0.57.0", default-features = false } wasip1 = { version = "1.0.0", path = "crates/wasip1", default-features = false } wasip2 = { version = "1.0.1", path = "crates/wasip2", default-features = false } wasip3 = { version = "0.1.1", path = "crates/wasip3", default-features = false } diff --git a/ci/regenerate.sh b/ci/regenerate.sh index 5508239..4cf00ca 100755 --- a/ci/regenerate.sh +++ b/ci/regenerate.sh @@ -100,7 +100,12 @@ generate_p2 crates/wasip2/src/proxy.rs \ # WASIp3 bindings generate_p3() { - generate "$@" ./crates/wasip3/wit --out-dir crates/wasip3/src + generate "$@" --std-feature ./crates/wasip3/wit --out-dir crates/wasip3/src + + sed -z -i 's/#\[unsafe(\n link_section = "\(.*\)"\n)\]/\ +#[cfg_attr(feature = "rustc-dep-of-std", unsafe(link_section = "\1-in-libstd"))]\ +#[cfg_attr(not(feature = "rustc-dep-of-std"), unsafe(link_section = "\1"))]\ +/' $file } generate_p3 crates/wasip3/src/imports.rs \ diff --git a/crates/wasip2/src/command.rs b/crates/wasip2/src/command.rs index aeb39b8..5b02c5c 100644 --- a/crates/wasip2/src/command.rs +++ b/crates/wasip2/src/command.rs @@ -1,4 +1,4 @@ -// Generated by `wit-bindgen` 0.54.0. DO NOT EDIT! +// Generated by `wit-bindgen` 0.57.0. DO NOT EDIT! // Options used: // * std_feature // * with "wasi:cli/environment@0.2.9" = "crate::cli::environment" @@ -167,7 +167,7 @@ macro_rules! __export_command_impl { exports::wasi::cli::run::__export_wasi_cli_run_0_2_9_cabi!($ty with_types_in $($path_to_types_root)*:: exports::wasi::cli::run); const _ : () = { #[rustfmt::skip] #[cfg(target_arch = "wasm32")] #[unsafe (link_section = - "component-type:wit-bindgen:0.54.0:wasi:cli@0.2.9:command:imports and exportsrust-wasip2-1.0.2+wasi-0.2.9-from-crates-io-command-world")] + "component-type:wit-bindgen:0.57.0:wasi:cli@0.2.9:command:imports and exportsrust-wasip2-1.0.2+wasi-0.2.9-from-crates-io-command-world")] #[doc(hidden)] #[allow(clippy::octal_escapes)] pub static __WIT_BINDGEN_COMPONENT_TYPE : [u8; 10773] = * b"\ @@ -387,8 +387,8 @@ nsecure-random-u64\x01\x02\x03\0\x1awasi:random/insecure@0.2.9\x05*\x01B\x03\x01 o\x02ww\x01@\0\0\0\x04\0\x0dinsecure-seed\x01\x01\x03\0\x1fwasi:random/insecure-\ seed@0.2.9\x05+\x01B\x03\x01j\0\0\x01@\0\0\0\x04\0\x03run\x01\x01\x04\0\x12wasi:\ cli/run@0.2.9\x05,\x04\0\x16wasi:cli/command@0.2.9\x04\0\x0b\x0d\x01\0\x07comman\ -d\x03\0\0\0G\x09producers\x01\x0cprocessed-by\x02\x0dwit-component\x070.245.1\x10\ -wit-bindgen-rust\x060.54.0"; +d\x03\0\0\0G\x09producers\x01\x0cprocessed-by\x02\x0dwit-component\x070.247.0\x10\ +wit-bindgen-rust\x060.57.0"; }; }; } @@ -397,8 +397,8 @@ pub use __export_command_impl as _export_command; #[rustfmt::skip] #[cfg(target_arch = "wasm32")] -#[cfg_attr(feature = "rustc-dep-of-std", unsafe(link_section = "component-type:wit-bindgen:0.54.0:wasi:cli@0.2.9:command-with-all-of-its-exports-removed:encoded worldrust-wasip2-1.0.2+wasi-0.2.9-from-crates-io-command-world-in-libstd"))] -#[cfg_attr(not(feature = "rustc-dep-of-std"), unsafe(link_section = "component-type:wit-bindgen:0.54.0:wasi:cli@0.2.9:command-with-all-of-its-exports-removed:encoded worldrust-wasip2-1.0.2+wasi-0.2.9-from-crates-io-command-world"))] +#[cfg_attr(feature = "rustc-dep-of-std", unsafe(link_section = "component-type:wit-bindgen:0.57.0:wasi:cli@0.2.9:command-with-all-of-its-exports-removed:encoded worldrust-wasip2-1.0.2+wasi-0.2.9-from-crates-io-command-world-in-libstd"))] +#[cfg_attr(not(feature = "rustc-dep-of-std"), unsafe(link_section = "component-type:wit-bindgen:0.57.0:wasi:cli@0.2.9:command-with-all-of-its-exports-removed:encoded worldrust-wasip2-1.0.2+wasi-0.2.9-from-crates-io-command-world"))] #[doc(hidden)] #[allow(clippy::octal_escapes)] @@ -619,7 +619,7 @@ nsecure-random-u64\x01\x02\x03\0\x1awasi:random/insecure@0.2.9\x05*\x01B\x03\x01 o\x02ww\x01@\0\0\0\x04\0\x0dinsecure-seed\x01\x01\x03\0\x1fwasi:random/insecure-\ seed@0.2.9\x05+\x04\06wasi:cli/command-with-all-of-its-exports-removed@0.2.9\x04\ \0\x0b-\x01\0'command-with-all-of-its-exports-removed\x03\0\0\0G\x09producers\x01\ -\x0cprocessed-by\x02\x0dwit-component\x070.245.1\x10wit-bindgen-rust\x060.54.0"; +\x0cprocessed-by\x02\x0dwit-component\x070.247.0\x10wit-bindgen-rust\x060.57.0"; #[inline(never)] #[doc(hidden)] pub fn __link_custom_section_describing_imports() { diff --git a/crates/wasip2/src/imports.rs b/crates/wasip2/src/imports.rs index 9704cf2..b720d7c 100644 --- a/crates/wasip2/src/imports.rs +++ b/crates/wasip2/src/imports.rs @@ -1,4 +1,4 @@ -// Generated by `wit-bindgen` 0.54.0. DO NOT EDIT! +// Generated by `wit-bindgen` 0.57.0. DO NOT EDIT! // Options used: // * std_feature // * type_section_suffix: "rust-wasip2-1.0.2+wasi-0.2.9-from-crates-io" @@ -9997,8 +9997,8 @@ mod _rt { #[rustfmt::skip] #[cfg(target_arch = "wasm32")] -#[cfg_attr(feature = "rustc-dep-of-std", unsafe(link_section = "component-type:wit-bindgen:0.54.0:wasi:cli@0.2.9:imports:encoded worldrust-wasip2-1.0.2+wasi-0.2.9-from-crates-io-in-libstd"))] -#[cfg_attr(not(feature = "rustc-dep-of-std"), unsafe(link_section = "component-type:wit-bindgen:0.54.0:wasi:cli@0.2.9:imports:encoded worldrust-wasip2-1.0.2+wasi-0.2.9-from-crates-io"))] +#[cfg_attr(feature = "rustc-dep-of-std", unsafe(link_section = "component-type:wit-bindgen:0.57.0:wasi:cli@0.2.9:imports:encoded worldrust-wasip2-1.0.2+wasi-0.2.9-from-crates-io-in-libstd"))] +#[cfg_attr(not(feature = "rustc-dep-of-std"), unsafe(link_section = "component-type:wit-bindgen:0.57.0:wasi:cli@0.2.9:imports:encoded worldrust-wasip2-1.0.2+wasi-0.2.9-from-crates-io"))] #[doc(hidden)] #[allow(clippy::octal_escapes)] @@ -10218,8 +10218,8 @@ p}\x01@\x01\x03lenw\0\0\x04\0\x10get-random-bytes\x01\x01\x01@\0\0w\x04\0\x0eget nsecure-random-u64\x01\x02\x03\0\x1awasi:random/insecure@0.2.9\x05*\x01B\x03\x01\ o\x02ww\x01@\0\0\0\x04\0\x0dinsecure-seed\x01\x01\x03\0\x1fwasi:random/insecure-\ seed@0.2.9\x05+\x04\0\x16wasi:cli/imports@0.2.9\x04\0\x0b\x0d\x01\0\x07imports\x03\ -\0\0\0G\x09producers\x01\x0cprocessed-by\x02\x0dwit-component\x070.245.1\x10wit-\ -bindgen-rust\x060.54.0"; +\0\0\0G\x09producers\x01\x0cprocessed-by\x02\x0dwit-component\x070.247.0\x10wit-\ +bindgen-rust\x060.57.0"; #[inline(never)] #[doc(hidden)] pub fn __link_custom_section_describing_imports() { diff --git a/crates/wasip2/src/proxy.rs b/crates/wasip2/src/proxy.rs index 35c3068..8262022 100644 --- a/crates/wasip2/src/proxy.rs +++ b/crates/wasip2/src/proxy.rs @@ -1,4 +1,4 @@ -// Generated by `wit-bindgen` 0.54.0. DO NOT EDIT! +// Generated by `wit-bindgen` 0.57.0. DO NOT EDIT! // Options used: // * std_feature // * with "wasi:cli/stdin@0.2.9" = "crate::cli::stdin" @@ -7147,7 +7147,7 @@ macro_rules! __export_proxy_impl { with_types_in $($path_to_types_root)*:: exports::wasi::http::incoming_handler); const _ : () = { #[rustfmt::skip] #[cfg(target_arch = "wasm32")] #[unsafe (link_section = - "component-type:wit-bindgen:0.54.0:wasi:http@0.2.9:proxy:imports and exportsrust-wasip2-1.0.2+wasi-0.2.9-from-crates-io-proxy-world")] + "component-type:wit-bindgen:0.57.0:wasi:http@0.2.9:proxy:imports and exportsrust-wasip2-1.0.2+wasi-0.2.9-from-crates-io-proxy-world")] #[doc(hidden)] #[allow(clippy::octal_escapes)] pub static __WIT_BINDGEN_COMPONENT_TYPE : [u8; 7040] = * b"\ @@ -7291,7 +7291,7 @@ incoming-request\x02\x03\0\x09\x11response-outparam\x01B\x08\x02\x03\x02\x01\x14 m\x03\0\x02\x01i\x01\x01i\x03\x01@\x02\x07request\x04\x0cresponse-out\x05\x01\0\x04\ \0\x06handle\x01\x06\x04\0\x20wasi:http/incoming-handler@0.2.9\x05\x16\x04\0\x15\ wasi:http/proxy@0.2.9\x04\0\x0b\x0b\x01\0\x05proxy\x03\0\0\0G\x09producers\x01\x0c\ -processed-by\x02\x0dwit-component\x070.245.1\x10wit-bindgen-rust\x060.54.0"; +processed-by\x02\x0dwit-component\x070.247.0\x10wit-bindgen-rust\x060.57.0"; }; }; } @@ -7300,8 +7300,8 @@ pub use __export_proxy_impl as _export_proxy; #[rustfmt::skip] #[cfg(target_arch = "wasm32")] -#[cfg_attr(feature = "rustc-dep-of-std", unsafe(link_section = "component-type:wit-bindgen:0.54.0:wasi:http@0.2.9:proxy-with-all-of-its-exports-removed:encoded worldrust-wasip2-1.0.2+wasi-0.2.9-from-crates-io-proxy-world-in-libstd"))] -#[cfg_attr(not(feature = "rustc-dep-of-std"), unsafe(link_section = "component-type:wit-bindgen:0.54.0:wasi:http@0.2.9:proxy-with-all-of-its-exports-removed:encoded worldrust-wasip2-1.0.2+wasi-0.2.9-from-crates-io-proxy-world"))] +#[cfg_attr(feature = "rustc-dep-of-std", unsafe(link_section = "component-type:wit-bindgen:0.57.0:wasi:http@0.2.9:proxy-with-all-of-its-exports-removed:encoded worldrust-wasip2-1.0.2+wasi-0.2.9-from-crates-io-proxy-world-in-libstd"))] +#[cfg_attr(not(feature = "rustc-dep-of-std"), unsafe(link_section = "component-type:wit-bindgen:0.57.0:wasi:http@0.2.9:proxy-with-all-of-its-exports-removed:encoded worldrust-wasip2-1.0.2+wasi-0.2.9-from-crates-io-proxy-world"))] #[doc(hidden)] #[allow(clippy::octal_escapes)] @@ -7443,7 +7443,7 @@ i\x05\x01j\x01\x0b\x01\x07\x01@\x02\x07request\x08\x07options\x0a\0\x0c\x04\0\x0 handle\x01\x0d\x03\0\x20wasi:http/outgoing-handler@0.2.9\x05\x13\x04\05wasi:http\ /proxy-with-all-of-its-exports-removed@0.2.9\x04\0\x0b+\x01\0%proxy-with-all-of-\ its-exports-removed\x03\0\0\0G\x09producers\x01\x0cprocessed-by\x02\x0dwit-compo\ -nent\x070.245.1\x10wit-bindgen-rust\x060.54.0"; +nent\x070.247.0\x10wit-bindgen-rust\x060.57.0"; #[inline(never)] #[doc(hidden)] pub fn __link_custom_section_describing_imports() { diff --git a/crates/wasip3/Cargo.toml b/crates/wasip3/Cargo.toml index a340df1..fb09f85 100644 --- a/crates/wasip3/Cargo.toml +++ b/crates/wasip3/Cargo.toml @@ -15,6 +15,9 @@ rust-version.workspace = true all-features = true [features] +default = ["std", "bitflags"] +std = [] +bitflags = ["wit-bindgen/bitflags"] async-spawn = ["wit-bindgen/async-spawn"] http-compat = [ "dep:bytes", @@ -25,6 +28,9 @@ http-compat = [ ] wit-bindgen-macros = ["wit-bindgen/macros"] +# Unstable feature to support being a libstd dependency +rustc-dep-of-std = ["core", "alloc", "wit-bindgen/rustc-dep-of-std"] + [dependencies] # NB: async bindings require `std` right now so this doesn't optionally disable # `std`, it's intentionally always enabled. @@ -35,6 +41,10 @@ http-body = { version = "1.0.1", optional = true } http = { version = "1.3.1", optional = true } thiserror = { version = "2.0.17", optional = true } +# When built as part of libstd +core = { optional = true, workspace = true } +alloc = { optional = true, workspace = true } + [dev-dependencies] futures = "0.3.31" http = "1.3.1" diff --git a/crates/wasip3/src/command.rs b/crates/wasip3/src/command.rs index 297721e..411eca9 100644 --- a/crates/wasip3/src/command.rs +++ b/crates/wasip3/src/command.rs @@ -1,5 +1,6 @@ -// Generated by `wit-bindgen` 0.54.0. DO NOT EDIT! +// Generated by `wit-bindgen` 0.57.0. DO NOT EDIT! // Options used: +// * std_feature // * with "wasi:cli/environment@0.3.0-rc-2026-03-15" = "crate::cli::environment" // * with "wasi:cli/exit@0.3.0-rc-2026-03-15" = "crate::cli::exit" // * with "wasi:cli/stdin@0.3.0-rc-2026-03-15" = "crate::cli::stdin" @@ -179,7 +180,7 @@ macro_rules! __export_command_impl { exports::wasi::cli::run::__export_wasi_cli_run_0_3_0_rc_2026_03_15_cabi!($ty with_types_in $($path_to_types_root)*:: exports::wasi::cli::run); const _ : () = { #[rustfmt::skip] #[cfg(target_arch = "wasm32")] #[unsafe (link_section = - "component-type:wit-bindgen:0.54.0:wasi:cli@0.3.0-rc-2026-03-15:command:imports and exportsrust-wasip3-0.5.0+wasi-0.3.0-rc-2026-03-15-from-crates-io-command-world")] + "component-type:wit-bindgen:0.57.0:wasi:cli@0.3.0-rc-2026-03-15:command:imports and exportsrust-wasip3-0.5.0+wasi-0.3.0-rc-2026-03-15-from-crates-io-command-world")] #[doc(hidden)] #[allow(clippy::octal_escapes)] pub static __WIT_BINDGEN_COMPONENT_TYPE : [u8; 8219] = * b"\ @@ -341,8 +342,8 @@ p}\x01@\x01\x07max-lenw\0\0\x04\0\x19get-insecure-random-bytes\x01\x01\x01@\0\0w \x03\0-wasi:random/insecure-seed@0.3.0-rc-2026-03-15\x05\x1b\x01B\x03\x01j\0\0\x01\ C\0\0\0\x04\0\x03run\x01\x01\x04\0\x20wasi:cli/run@0.3.0-rc-2026-03-15\x05\x1c\x04\ \0$wasi:cli/command@0.3.0-rc-2026-03-15\x04\0\x0b\x0d\x01\0\x07command\x03\0\0\0\ -G\x09producers\x01\x0cprocessed-by\x02\x0dwit-component\x070.245.1\x10wit-bindge\ -n-rust\x060.54.0"; +G\x09producers\x01\x0cprocessed-by\x02\x0dwit-component\x070.247.0\x10wit-bindge\ +n-rust\x060.57.0"; }; }; } @@ -350,9 +351,10 @@ n-rust\x060.54.0"; pub use __export_command_impl as _export_command; #[rustfmt::skip] #[cfg(target_arch = "wasm32")] -#[unsafe( - link_section = "component-type:wit-bindgen:0.54.0:wasi:cli@0.3.0-rc-2026-03-15:command-with-all-of-its-exports-removed:encoded worldrust-wasip3-0.5.0+wasi-0.3.0-rc-2026-03-15-from-crates-io-command-world" -)] + +#[cfg_attr(feature = "rustc-dep-of-std", unsafe(link_section = "component-type:wit-bindgen:0.57.0:wasi:cli@0.3.0-rc-2026-03-15:command-with-all-of-its-exports-removed:encoded worldrust-wasip3-0.5.0+wasi-0.3.0-rc-2026-03-15-from-crates-io-command-world-in-libstd"))] +#[cfg_attr(not(feature = "rustc-dep-of-std"), unsafe(link_section = "component-type:wit-bindgen:0.57.0:wasi:cli@0.3.0-rc-2026-03-15:command-with-all-of-its-exports-removed:encoded worldrust-wasip3-0.5.0+wasi-0.3.0-rc-2026-03-15-from-crates-io-command-world"))] + #[doc(hidden)] #[allow(clippy::octal_escapes)] pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 8226] = *b"\ @@ -514,7 +516,7 @@ p}\x01@\x01\x07max-lenw\0\0\x04\0\x19get-insecure-random-bytes\x01\x01\x01@\0\0w \x03\0-wasi:random/insecure-seed@0.3.0-rc-2026-03-15\x05\x1b\x04\0Dwasi:cli/comm\ and-with-all-of-its-exports-removed@0.3.0-rc-2026-03-15\x04\0\x0b-\x01\0'command\ -with-all-of-its-exports-removed\x03\0\0\0G\x09producers\x01\x0cprocessed-by\x02\ -\x0dwit-component\x070.245.1\x10wit-bindgen-rust\x060.54.0"; +\x0dwit-component\x070.247.0\x10wit-bindgen-rust\x060.57.0"; #[inline(never)] #[doc(hidden)] pub fn __link_custom_section_describing_imports() { diff --git a/crates/wasip3/src/http_compat/body_writer.rs b/crates/wasip3/src/http_compat/body_writer.rs index 4d7f804..c892f4a 100644 --- a/crates/wasip3/src/http_compat/body_writer.rs +++ b/crates/wasip3/src/http_compat/body_writer.rs @@ -6,6 +6,7 @@ use crate::{ use http::HeaderMap; use http_body::{Body as _, Frame}; use std::future::poll_fn; +use std::prelude::v1::*; use std::{fmt::Debug, pin}; type BoxError = Box; diff --git a/crates/wasip3/src/http_compat/conversions.rs b/crates/wasip3/src/http_compat/conversions.rs index 0c22d88..9297fdd 100644 --- a/crates/wasip3/src/http_compat/conversions.rs +++ b/crates/wasip3/src/http_compat/conversions.rs @@ -1,26 +1,13 @@ use super::{ - to_internal_error_code, - RequestOptionsExtension, - IncomingRequestBody, - IncomingResponseBody, - Request as HttpRequest, - Response as HttpResponse, - body_writer::BodyWriter, + body_writer::BodyWriter, to_internal_error_code, IncomingRequestBody, IncomingResponseBody, + Request as HttpRequest, RequestOptionsExtension, Response as HttpResponse, }; use crate::http::types::{ - ErrorCode, - Fields, - HeaderError, - Headers, - Method, - Scheme, - Request as WasiHttpRequest, - Response as WasiHttpResponse, -}; -use std::{ - any::Any, - convert::TryFrom, + ErrorCode, Fields, HeaderError, Headers, Method, Request as WasiHttpRequest, + Response as WasiHttpResponse, Scheme, }; +use std::prelude::v1::*; +use std::{any::Any, convert::TryFrom}; /// Converts a host-side HTTP response (`HttpResponse`) into a WASI HTTP response (`WasiHttpResponse`). /// @@ -28,7 +15,7 @@ use std::{ /// serializing status codes, headers, and body data into their WebAssembly-compatible /// representations. It supports generic response body types and streams the response /// asynchronously into the WASI environment. -/// +/// /// # See Also /// /// - [`http_from_wasi_response`] — converts a WASI response back into a host-side HTTP response. @@ -38,7 +25,7 @@ pub fn http_into_wasi_response(mut resp: HttpResponse) -> Result>, - T::Error: Into> + T::Error: Into>, { if let Some(incoming_body) = (&mut resp as &mut dyn Any).downcast_mut::() { @@ -55,8 +42,7 @@ where let (body_writer, body_rx, body_result_rx) = BodyWriter::new(); - let (response, _future_result) = - WasiHttpResponse::new(headers, Some(body_rx), body_result_rx); + let (response, _future_result) = WasiHttpResponse::new(headers, Some(body_rx), body_result_rx); _ = response.set_status_code(resp.status().as_u16()); @@ -74,7 +60,7 @@ where /// This function performs the reverse operation of [`http_into_wasi_response`], translating /// the fields and body of a response from the WASI HTTP model into the conventional Rust /// `http` crate representation. -/// +/// /// # See Also /// /// - [`http_into_wasi_response`] — the inverse conversion. @@ -107,10 +93,9 @@ pub fn http_into_wasi_request(mut req: HttpRequest) -> Result>, - T::Error: Into> + T::Error: Into>, { - if let Some(incoming_body) = (&mut req as &mut dyn Any).downcast_mut::() - { + if let Some(incoming_body) = (&mut req as &mut dyn Any).downcast_mut::() { if let Some(request) = incoming_body.take_unstarted() { return Ok(request); } @@ -124,10 +109,7 @@ where .cloned() .map(|o| o.0); - let headers = parts - .headers - .try_into() - .map_err(to_internal_error_code)?; + let headers = parts.headers.try_into().map_err(to_internal_error_code)?; let (body_writer, contents_rx, trailers_rx) = BodyWriter::new(); @@ -161,7 +143,7 @@ where /// from the WASI HTTP model into a conventional Rust `http` request type. It reconstructs /// the URI, method, headers, extensions, and body so that the request can be used directly /// by host HTTP clients, servers, or middleware. -/// +/// /// # See Also /// /// - [`http_into_wasi_request`] — converts from host HTTP requests into WASI requests. @@ -185,9 +167,7 @@ pub fn http_from_wasi_request(req: WasiHttpRequest) -> Result