feat(wasm): add support for the stable target wasm32-wasip2
Fixes #2294
~Depends on https://github.com/servo/rust-url/pull/983~
This PR, in order of commits:
- Adds target conditionals to separate the compilation of
reqwestin the generalwasm32OS and thewasm32-wasip2target (which is now a tier 2 target and Rust stable in 1.82) - Adds .vscode to the .gitignore (I can remove this if it's undesired)
- Adds
wasm32-wasip2implementations forreqwestso that you can compile WebAssembly components and make outgoing requests that compile down towasi:httpbindings ~- This commit also adds a patch for crates.io that depends on https://github.com/servo/rust-url/pull/983, which is why this PR is a draft. There is no significant functionality change upstream to make the wasm32-wasip2 target work for theurlcrate, just a change to remove an unstable feature flag.~ - Adds an example
wasm_componentto illustrate how this crate can be used in the context of awasm32-wasip2program.
I've attempted to bring over the minimal implementations into the wasm32-wasip2 code, e.g. no multipart support, to keep the review focused and simple to start. If any of these need to be added, I'm happy to add follow-up commits after the review.
Apologies for letting this go stale here, I haven't had the time to really shore this one up. I think there's a lot of promise in this approach, and I also don't want to overindex on supporting wasi:[email protected] if we could possibly support it using a combination of the stdlib and tokio in this crate.
I think in the shorter term what would make this PR a candidate for review and merging would either be:
- Integration into the async reqwest using a wasm-compatible async runtime (like tokio)
- Integration into the blocking reqwest as-is (which I've looked into, and may be more complicated than first meets the eye)
Integration into the async reqwest using a wasm-compatible async runtime (like tokio)
Something to call out is that at least some tokio features do break on wasm if naively depended on, ref https://github.com/seanmonstar/reqwest/issues/2509
Specifically, the use of the tokio timer seems to cause issues. You'll see that there is currently conditional compilation to keep wasm platforms from relying on tokio/time and tower/timeout. Just something to keep in mind if trying to pull wasm support into the async client, it'll take some refactoring.
Perhaps I'm lacking context and wasm32-wasip2 and this isn't an issue for that platform, which is cool if so. Anyway still will need to tweak the conditional compilation accordingly.
The issue with this PR is that you can't really use this version with libraries depending on reqwest: all the IO here is sync and the native reqwest is not.
I've been looking into recently making reqwest to work without extra code in this crate. We can base the IO on mio and tokio, and what I have right now is kind of working reqwest that can connect to http hosts.
The issue is that we miss a TLS implementation we can use with wasip2. Ring or AWS will not link in wasip2, so that ended my exploration with just using modified mio and tokio to drive reqwest as it is today in main.
The question is what is the way forward. We naturally want to start using the async ecosystem in wasip2. And it is hard requirement for many crates that we must use tokio for some reason.
@brooksmtownsend here's my past few days on the wasi async ecosystem written down, you might be interested:
https://gist.github.com/pimeys/856846ff8718247d79f1557ed82d80f7
My version does not do that many modifications in reqwest, most of the changes are in mio.