Order of accessing my objects

Hi, newbie here. I'm trying to build a server web using tokio, hyper, routerify and redis.

In a route function, I'm accessing the redis::Client using routerify::RouterBuilder::data and getting the body with hyper::body::to_bytes

Here is my code:

pub async fn handler(req: Request<Body>) -> Result<Response<Body>, Infallible> {
    let state = req.data::<redis::Client>().unwrap();
    let mut conn = redis::aio::ConnectionManager::new(state.clone()).await.unwrap();
    let body = hyper::body::to_bytes(req.into_body());
    // do something with body

And it's working like that.

But my concern is:
I need to check if the body is well formatted and if not, I would like to avoid the connection to redis.

I simply (newbily) thought I just need to read the body before connecting to redis, but computer says no.
I understand that hyper::Request::into_body as taking the ownership, and that's cool.
So I try different things by swapping these 3 lines around and following the errors one by one like a monkey typing on a typewriter.

What am I missing here?

You absolutely can just read the body as the first thing. I don't think that in itself is a problem. What error are you exactly getting?

If you call req.data() after calling req.into_body(), you'll get an error that req can no longer be used because the value has been moved out of it.

You can avoid this by using req.body_mut() instead of into_body.

1 Like

If I read the body with req.into_body(), I got an error when getting the redis client with req.data:: with the message:
borrow of moved value: req

I'm getting two errors:

  1. cannot borrow req as mutable, as it is not declared as mutable
  2. cannot borrow req as immutable because it is also borrowed as mutable

Please post the code that gave that error along with the full error.

1 Like
pub async fn handler(mut req: Request<Body>) -> Result<Response<Body>, Infallible> {
    let body = hyper::body::to_bytes(req.body_mut());
    let state = req.data::<redis::Client>().unwrap();
    let mut conn = ConnectionManager::new(state.clone()).await.unwrap();
15 |     let body = hyper::body::to_bytes(req.body_mut());
   |                                      --- mutable borrow occurs here

18 |     let state = req.data::<redis::Client>().unwrap();
   |                 ^^^ immutable borrow occurs here

That is not the full error. Don't strip context

2 Likes

It seems like you're missing an await.

But yes, please do not remove stuff from errors. They're a lot more useful if you include the full error.

1 Like

Ok, I understand:


error[E0502]: cannot borrow `req` as immutable because it is also borrowed as mutable
  --> src/mobile/add_friend.rs:18:17
   |
15 |     let body = hyper::body::to_bytes(req.body_mut());
   |                                      --- mutable borrow occurs here
...
18 |     let state = req.data::<redis::Client>().unwrap();
   |                 ^^^ immutable borrow occurs here
...
54 | }
   | - mutable borrow might be used here, when `body` is dropped and runs the destructor for type `impl Future`
1 Like

It's seems true (on the body var), I will investigates.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.