HTTP library with wasm32-wasi support

I'm working on a project where I need to create a Rust application that makes an HTTP call, but I need a library that is compatible with wasm32-wasi, because in the end I need to generate an application binary.

Would gloo-net work for you?

Thanks for the answer, but it didn't work when I generate the binary using the command cargo build --target wasm32-wasi --release it shows an error in the library

Too bad. I have only a rudimentary understanding of wasi, I was hoping it'd expose the browser APIs needed by gloo-net to work. When I quickly searched for Rust HTTP clients that support wasi I came up with hyper_wasi — Rust HTTP client // Lib.rs, maybe that's worth a shot?

This isn't possible with the wasm32-wasi target because the version of WASI that the Rust standard library binds to, WASI preview 1, doesn't provide a way to create TCP connections. It only has the ability to communicate over sockets that were already preopened by the runtime, which isn't very useful for you. That means APIs like std::net::TcpStream::connect() will always fail.

If you want to make HTTP requests, you'll need the WebAssembly runtime to provide you with a way to do this on top of WASI.

WASI preview 2 (the next version of WASI, rewritten by The Bytecode Alliance in terms of the Component Model) should provide a way to do networking, but it's not finalised yet and hasn't been wired into the Rust standard library. I haven't had a chance to use it too much yet, so I don't know how you'd compile your library and start making HTTP calls. This preview of WASI is also only supported by the Wasmtime runtime.

There is also WASIX, an extension to the original WASI preview 1 made by Wasmer (where I work) which adds more POSIX functionality. You can use cargo wasix build to compile a Rust program for WASIX and they've got a patched version of the reqwest crate you can use for making HTTP requests. However, similar to WASI preview 2, WASIX comes with the caveat that it's only supported by the Wasmer runtime. One nice thing is that their fork of reqwest works when running on a host as well as when compiled to wasm32-unknown-wasmer.

If you are running in the browser, you can compile for wasm32-unknown-unknown and use the web-sys crate to call the normal fetch() function from JavaScript. That's what gloo-net will be doing under the hood.

Otherwise, if you are implementing the host, you should be able to expose some custom functions to your guest which will make HTTP requests. How you do that will depend on the WebAssembly runtime you are using and their API. It might get a bit tricky because a lot of WASI implementations try to take control of how imports are set up and don't make it easy to provide extra functions.

TL;DR: The WASI landscape is a bit undeveloped at the moment and any approach you go with will incur some level of lock-in. Choose a solution based on where your WebAssembly is going to run.

2 Likes

Thanks for the answer... I'm new to Rust and I'm in a project where I need to develop an application that makes a request for password validation.
So I developed this function:

fn valida_senha(senha: &str) -> Result<StatusCode, reqwest::Error>{
let url = format!("https://valida_senha?senha={}", senha);
let response = reqwest :: blocking :: get(url)?;

Ok(response.status())

}

however, when executing the cargo build --target wasm32-wasi --release command to generate the binary, the error appears:

error[E0433]: failed to resolve: could not find blocking in reqwest
--> src/lib.rs:70:31
|
70 | let response = reqwest :: blocking :: get(url)?;
| ^^^^^^^^ could not find blocking in reqwest

For more information about this error, try rustc --explain E0433.
error: could not compile flex_gateway_policy (lib) due to previous error

reqwest's blocking feature doesn't work on any wasm32 target: reqwest - Rust

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.