Rust Error the trait `Body` is not implemented for `Vec<u8>` hyper::client::conn::http1::handshake(io).await?;

26 Views Asked by At

First let me say that I am very new to Rust, but I have been a developer for many years.

I am trying to build an application that reads RSS feeds using the Tokio & hyper crates. I am using the RustRover 2023.3 EAP IDE, and rustc 1.77.1 (7cf61ebde 2024-03-27).

I started with the example code from here -> text and I have not been able to resolve this error:

error[E0277]: the trait bound `Vec<u8>: Body` is not satisfied
   --> rss_sample/src/fetch_data.rs:35:38
    |
35  |             let (mut sender, conn) = hyper::client::conn::http1::handshake(io).await?;
    |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Body` is not implemented for `Vec<u8>`
    |
    = help: the following other types implement trait `Body`:
              BoxBody<D, E>
              UnsyncBoxBody<D, E>
              hyper::body::Incoming
              Box<T>
              http_body_util::Empty<D>
              Collected<B>
              http_body_util::combinators::MapErr<B, F>
              MapFrame<B, F>
            and 11 others
note: required by a bound in `hyper::client::conn::http1::handshake`

Here is the function:

pub async fn fetch_data(uri: String, method: hyper::Method, mime_type: String, request_data: Vec<u8>) -> Result<String, Box<dyn Error>> {
        let mut body: String = String::new();
        let the_url = hyper::Uri::from_str(&*uri);
        if the_url.is_err() {
            log::error!("failed to parse URL {}", uri);
        } else {
            let default_port = if uri.starts_with("https://") { 443 } else { 80 };
            let url = the_url.unwrap();
            let host = url.host().expect("uri has no host");
            let port = url.port_u16().unwrap_or(default_port);
            let addr = format!("{}:{}", host, port);

            let stream = TcpStream::connect(addr).await?;
            let io = TokioIo::new(stream);

            let (mut sender, conn) = hyper::client::conn::http1::handshake(io).await?;
            tokio::task::spawn(async move {
                if let Err(err) = conn.await {
                    log::error!("Connection failed: {:?}", err);
                }
            });

            let authority = url.authority().unwrap().clone();

            let path = url.path();
            let req = hyper::Request::builder()
                .uri(path)
                .method(method)
                .header(hyper::header::HOST, authority.as_str())
                .header(hyper::header::CONTENT_TYPE, mime_type)
                .header(hyper::header::USER_AGENT, get_user_agent_string())
                .body(request_data)?;

            let mut res = sender.send_request(req).await?;

            log::debug!(
                "------------------------------ {}\nResponse: {}\nHeaders: {:#?}",
                uri,
                res.status(),
                res.headers()
            );

            let b = res.into_body().collect().await?.to_bytes();
            body = String::from_utf8_lossy(&*b).parse().unwrap();
        }
        Ok(body)
    }

I am hoping to be able to read from multiple RSS sources, then combine and process the feed data. The same fetch_data() function will be used to post the processed data to another site.

0

There are 0 best solutions below