Hyper: reading body and passing it to a function?

#1

Hello,
I have the following hyper code (hyper version 0.12.17)

fn do_stuff_with_body(body_str: String) {
    ()
}

fn read_body(req: Request<Body>) -> BoxFut {
    let mut response = Response::new(Body::empty());

    match (req.method(), req.uri().path()) {

        (&Method::POST, "/read/") => {
            println!("a1");
            let body = req.into_body();
            println!("a2");
            let value = body.concat2().wait().unwrap().to_vec();

            println!("value: {:?}", &value);
            do_stuff_with_body(String::from_utf8(value).unwrap());
            //*response.body_mut() = Body::from("aa"); //wrap_stream(mapping);
        }

        _ => {
            *response.status_mut() = StatusCode::NOT_FOUND;
        }
    };

    Box::new(future::ok(response))
}

I want to extract the body (here a simple String, later a more complex json document using serde).

I found the example using wait() somewhere on the web but it seems to block.
When running, it prints “a1” and “a2” but never progresses beyond the wait() call.

What is the best practice to extract the body of a HTTP request and pass it as a String or something else to a function?

Any help very much appreciated.

Regards,
Markus

#2

In the vast majority of cases, you should never call wait() on a future - this forces the current thread to await the future’s completion, but if the current thread happens to be running the event loop/reactor, you’ll deadlock. Instead, the approach is to chain continuations (by using the various Future/Stream combinators) onto the futures - those continuations receive the value (and/or error, depending on the combinator) the previous future resolved to, and you can then make use of that value.

Take a look at the “Buffering the Request Body” section on hyper’s site for a feel for how this might look.

1 Like
#3

Thanks! That helped.
I’ve rewritten parts of the code and now it works with futures.