emilk / ehttp Goto Github PK
View Code? Open in Web Editor NEWMinimal Rust HTTP client for both native and WASM
License: Apache License 2.0
Minimal Rust HTTP client for both native and WASM
License: Apache License 2.0
pub headers: BTreeMap<String, String>
The headers in http requests can have the same key.
Whenever I need to test a local wasm, I kept getting CORS errors since all requests uses mode cors (https://github.com/emilk/ehttp/blob/master/ehttp/src/web.rs#L45C5-L45C43). It would be nice to be able to configure on request which mode we would like to use, like no-cors
.
This only affects wasm, tho, since CORS is something only available on browsers.
Would it be possible to get some documentation on how to connect ehttp to perform https requests submitted with cookies, and how those cookies can be set via the response? Thanks!
Hi ,
I am developing a tool that read info from a device via http and I am using egui + ehttp for this problem.
For this device, I need to make 2 requests to get the last content I want
First, I need to make a request to: "http://192.168.0.11/abcxyz" then the device will return a result that contains a temp link inside.
I will use regex to get the temp link then make the second request to device: "http://192.168.0.11/templink"
The result will return the info I need.
The problem is: I want to make the full request (first and second request) after an interval time, let says: 1 minutes.
Could you give me an advice of doing this?
I love the simple API of this crate! It can be useful if ehttp
supports saving cookies, such as login function. Currently, the "agent" (ureq::Agent type) is not continuous between each request.
A cross-platform and object-oriented example might look like this:
pub struct Agent {
#[cfg(not(target_arch = "wasm32"))]
agent: ureq::Agent,
}
// save the session if we need (compatible syntax)
let session = Agent::new();
session.fetch(req, |r| match r {
Ok(r) if r.ok => alert("Login successfully!"),
_ => alert("Login failed!"),
});
// original "fetch" function
fetch(req, |r| match r {
Ok(r) if r.ok => alert("Login successfully!"),
_ => alert("Login failed!"),
});
Hi, due to the use of the "document features" crate, this crate won't build when vendoring dependencies. (slint-ui/document-features#20)
Would it be possible to place this behind a feature flag or sth similar to make building with vendored dependencies possible? That's relevant eg when packaging for nix.
error: Could not find documented features in Cargo.toml
--> /private/tmp/nix-build-rerun-cli.drv-0/rerun-cli-vendor.tar.gz/ehttp/src/lib.rs:21:10
|
21 | #![doc = document_features::document_features!()]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
I wanted to use ehttp for a project of mine where I need to make a request (no use of async/await), get the response text from that request, and deserialize it with Serde. I am having some trouble finding a way to get the response value outside of the callback closure in the fetch
function so I can pass the response text into Serde. Is there any way to do this?
This may be intended behavior since the suggestion in #51 seems to recommend it explicitly. But after #52, instantiating Request
needs a conditional compile if targeting both wasm and native to account for the new mode
field.
This was also more difficult to figure out than necessary because the docs don't have a wasm platform listed -- so the mode
field is just not present anywhere on https://docs.rs/ehttp/latest/ehttp/struct.Request.html regardless of platform target choice.
The workaround of adding
#[cfg(target_arch = "wasm32")]
mode: ehttp::Mode::Cors,
to all Request
instantiations is not all that bad, but the lack of documentation makes it more cumbersome than it needs to be. Maybe deriving default for Request
would make it a little more clean, but still the lack of documentation seems to be the main issue.
I don't have any suggestions for a real fix, maybe something simple like adding a mode field for native as well? Anyway, feel free to close this issue if things are working as intended for everyone else.
I used https://github.com/rust-cross/cargo-xwin to cross compile the example_eframe on macOS to windows and attempted to run on windows 10. Windows Defender thinks this is Win32/Wacatac.H!ml
Hi,
Is there a way to ignore TLS cert expiration?
Hello,
I am not sure if this is a bug, or a mistake from my end.
I am trying the streaming api in the following:
pub fn retrieve_response_async(
param: ReportDeps,
content: Arc<Mutex<String>>,
toasts: Arc<Mutex<Toasts>>,
boolean_flag: Arc<AtomicBool>,
) {
let flag = boolean_flag.clone();
let url = "http://127.0.0.1:8000/reportstream";
let request = ehttp::Request::post(url, serde_json::to_vec(¶m).unwrap());
ehttp::streaming::fetch(
request,
move |result: ehttp::Result<ehttp::streaming::Part>| {
let part = match result {
Ok(part) => part,
Err(err) => {
boolean_flag
.clone()
.store(false, std::sync::atomic::Ordering::Relaxed);
toasts
.lock()
.error(format!("An error occurred while streaming `{url}`: {err}"));
return std::ops::ControlFlow::Break(());
}
};
match part {
ehttp::streaming::Part::Response(response) => {
tracing::info!("RESPONSE");
println!("Status code: {:?}", response.status);
if response.ok {
std::ops::ControlFlow::Continue(())
} else {
boolean_flag.store(false, std::sync::atomic::Ordering::Relaxed);
toasts.lock().error(format!(
"An error occured, please try again: {}",
response.status_text
));
std::ops::ControlFlow::Break(())
}
}
ehttp::streaming::Part::Chunk(chunk) => {
if chunk.is_empty() {
flag.clone()
.store(false, std::sync::atomic::Ordering::Relaxed);
std::ops::ControlFlow::Break(())
} else {
let chunk = String::from_utf8(chunk).unwrap();
tracing::info!("{:?}", chunk);
content.lock().push_str(&chunk);
std::ops::ControlFlow::Continue(())
}
}
}
},
);
}
As of current, this is only resolving after the request has completed. Note that I'm using a streaming response from actix:
#[post("/reportstream")]
pub async fn report(payload: web::Payload) -> impl Responder {
let ReportDeps {
doctor_input,
age,
name,
sex,
date,
} = type_cast::<ReportDeps>(payload).await;
let (mut tx, rx) = futures::channel::mpsc::unbounded::<
std::result::Result<actix_web::web::Bytes, std::io::Error>,
>();
let mut result = client.chat().create_stream(request).await.unwrap();
tokio::task::spawn(async move {
while let Some(message) = result.next().await {
let message = match message {
Ok(message) => {
if let Some(message) = message.choices[0].delta.content.clone() {
message.clone()
} else {
String::new()
}
}
Err(e) => e.to_string(),
};
let _ = tx.start_send(Ok(Bytes::from(message)));
}
});
/// This works and results in a streamed response
HttpResponse::Ok().streaming(rx)
}
As you see, the response is coming in, but its chunks are not being handled as they are coming in, instead, the streaming api is waiting until the end of the response.
Note that curl --no-buffer "127.0.0.1:8000/reportstream"
gives a chunked response.
I failed to use this crate to download a PDF file using a web worker.
The source code only works in the main thread since it needs to access the window object from web_sys.
let window = web_sys::window().unwrap();
Is it possible to support it in a web worker?
Currently I am trying to use channels receiver for wasm runtime:
let (sender, receiver) = mpsc::channel();
ehttp::fetch(ehttp::Request::get(&url), move |response: ehttp::Result<ehttp::Response>| {
let result = response.unwrap();
sender.send(result);
});
...
let response = receiver.recv().unwrap();
But it fails with error - panicked at 'condvar wait not supported', library/std/src/sys/wasm/../unsupported/locks/condvar.rs:20:9:
As I get it from other internet resources that it is not possible to use channels in wasm.
Can you please confirm that it is an issue or share an example how it is possible to fetch using channels?
I have a library crate to which I'm trying to add unit tests. The crate builds just fine using trunk and runs when used in a project, but when I try to build the tests (cargo build --tests --target wasm32-unknown-unknown
) I get the following error:
--> C:\Users\jonas.vanderaa\.cargo\registry\src\index.crates.io-6f17d22bba15001f\ehttp-0.3.1\src\web.rs:34:22
|
34 | web_sys::console::error_1(&value);
| ^^^^^^^ could not find `console` in `web_sys`
Any idea what's causing this?
Hi,
Thanks for making this library, it makes a lot of sense and simplifies the code using it that would need to work across both native and wasm. I want to use reqwest for my use case so going to do something similar built on reqwest instead. In doing that I was looking at this library and realized that version 1.61 of rust is specified in the rust-toolchain file. One of the dependencies bumped their MSRV and as a result rust-analyzer gives and error when I open the workspace in VS Code. See error below:
[ERROR rust_analyzer::main_loop] FetchBuildDataError:
error: package `raw-window-handle v0.5.2` cannot be built because it requires rustc 1.64 or newer, while the currently active rustc version is 1.61.0
[ERROR flycheck] Flycheck failed to run the following command: cd "/home/one/ehttp" && "cargo" "clippy" "--workspace" "--message-format=json-diagnostic-rendered-ansi" "--manifest-path" "/home/one/ehttp/Cargo.toml" "--all-targets"
[ERROR rust_analyzer::lsp_utils] cargo check failed:
Cargo watcher failed, the command produced no valid metadata (exit code: ExitStatus(unix_wait_status(25856))):
error: package `raw-window-handle v0.5.2` cannot be built because it requires rustc 1.64 or newer, while the currently active rustc version is 1.61.0
https://i.redd.it/un44882dvyj21.jpg
.JsValue(TypeError: NetworkError when attempting to fetch resource.)
Expected success, or at least a better error message.
cargo run --release -p example_eframe
Finished release [optimized] target(s) in 0.05s
Running `/home/user/Desktop/ehttp/target/release/example_eframe`
[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
example_eframe: xcb_io.c:269: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.
[1] 21354 abort (core dumped) cargo run --release -p example_eframe
rustup --version
rustup 1.24.3 (2021-06-08)
info: This is the version for the rustup toolchain manager, not the rustc compiler.
info: The currently active `rustc` version is `rustc 1.57.0-nightly (e1e9319d9 2021-10-14)`
cargo --version
cargo 1.57.0-nightly (c7957a74b 2021-10-11)
Perhaps I'm doing something wrong, but when I use wasm-pack with a --target of nodejs and then run in a simple node test script, it panics as shown below.
panicked at 'called Option::unwrap()
on a None
value', ...\ehttp-0.3.0\src\web.rs:37:36
It seems this points to code that is expecting it to be run in a browser. Any chance there may be a way to support node?
Thanks!
I want to highlight that struct Request has field mode: Mode
: https://docs.rs/ehttp/0.5.0/src/ehttp/types.rs.html#146 that is not documented in docs.rs, since it has #[cfg(target_arch = "wasm32")]
.
This can create confusion when developing for wasm.
Thank for your great work
It seems that the headers field of the Request
struct remains unused when compiling to WASM. From what I can tell this is because they are set via a getter here and therefore remain unused.
From a quick glance at the web-sys docs the correct way to set headers is by passing a Headers
struct to the RequestInit
instead. I might be able to test this and make a PR later this week.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.