WebAssembly support
brandonros opened this issue · 7 comments
I don't know why I expected this to work with WebAssembly (it compiles for the wasm32-unknown-unknown
target if you disable any TLS/SSL features).
But you will get to JavaScript layer and have one of what I guess is many issues (how would it know to do HTTP over fetch()
?):
panicked at 'time not implemented on this platform', library/std/src/sys/wasm/../unsupported/time.rs:13:9
Stack:
Error
at http://localhost:8080/pkg/graphql_poc.js:188:21
Which comes from
let agent = AgentBuilder::new()
.timeout_read(Duration::from_secs(30))
.timeout_write(Duration::from_secs(30))
.build();
I read you can use Chrono::Duration (which does support WASM) but AgentBuilder would need to accept non std::time::Duration?
Hi @brandonros! Welcome to ureq!
I have never used WebAssembly myself, so I don't actually know what would be required to make that work. The Duration
here are ultimately used as socket timeouts. Those sockets are std::net::TcpStream
, and I'll imagine that even if we get past the Duration
problems, we will get to a dead end for the sockets. I don't know if it would be possible to solve that – blocking sockets at the bottom of the call stack?
A possible direction for a ureq 3.0, would be to isolate the HTTP request/response function into a Sans IO pattern backing library without allocations, deliberately target no_std and webassembly. Then make nice higher level wrappers for std, no_std and webasm that sits on the same core.
I'm curious @brandonros, what's the use case for using ureq in WebAssembly?
If it's useful, we could probably do something where all the meaningful features are stubbed out to fetch
, but we'd need some motivating use cases.
I do really like the idea of making a no_std version of ureq (with more user-friendly features stacked on top when std is present).
@jsha i've been thinking about the no_std thing.
Here's an experiment just fleshing out what a no_std low level API could look like: https://github.com/algesten/h1-call
Design goals:
no_std
and no alloc crate. Stack is enough- Sans-IO. Bring your own transport.
- Allow flushing the buffer to the transport at any point. I.e. do not require all headers to be in the borrowed buffer at the same time.
- Encode protocol as types, i.e. let
State
mean "the state the call is currently in",Version
means Http/1.0 or 1.1.Method
means GET/HEAD/etc... - Using types, constraint operations to only those that are valid. I.e.
Version
HTTP/1.0
cannot send a body unless theMethod
isPOST
(the others are GET/HEAD which cannot have a body).
I've fleshed out how this could look with HTTP/1.0 – but it looks pretty promising, albeit it's a type soup.
I'm curious @brandonros, what's the use case for using ureq in WebAssembly?
If it's useful, we could probably do something where all the meaningful features are stubbed out to
fetch
, but we'd need some motivating use cases.I do really like the idea of making a no_std version of ureq (with more user-friendly features stacked on top when std is present).
You're probably right. My "vision"/idea was probably due to a lack of understanding on how things should be done in wasm
land but the argument was:
write once, be able to run it backend (native Rust binary) and/or in the browser with wasm
without having to add logic like if backend, use ureq, otherwise, use web-sys fetch
https://github.com/search?q=repo%3Arustwasm%2Fwasm-bindgen%20fetch_with_request&type=code