Code Monkey home page Code Monkey logo

ehttp's Introduction

Hi there ๐Ÿ‘‹ ๐Ÿ˜Š

I'm Emil Ernerfeldt, and I like Rust!

I'm the creator of egui, the friendly GUI library.

I am also the co-founder of Rerun, a company making visualization tooling for computer vision and robotics.

Follow me on twitter @ernerfeldt for news about egui and Rerun :)

ehttp's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

ehttp's Issues

Headers field unused on WASM

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.

Support for nodejs

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!

Headers need same key

pub headers: BTreeMap<String, String>

The headers in http requests can have the same key.

Old version of rust specified

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

Keep `ureq::Agent` for native clients

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!"),
});

Build fails with vendored dependencies

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!()]
   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |

Test app crashes

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)

Fetching using channels

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:
Screenshot 2023-02-28 at 16 45 47

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?

ehttp is not passing the `console` feature to `web-sys`

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?

Conditional Compile Required for Requests

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.

Blocking untill the end of the response?

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(&param).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)
}

image

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.

How to do callback in fetch function

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?

Documentation for HTTPS Request with cookie?

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!

Make sequence request to a device in an interval time with egui + ehttp?

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.