Hyper request as string

Viewed 476

I would like to be able to print out the entire unparsed request so that I can easily see exactly what information the request contains. I could write a function to recreate the request string from the parsed request by iterating over all the headers etc, but I was hoping there would be an easier way by accessing the unparsed request. Is this possible with Hyper? The below example is taken from the Hyper website and demonstrates how I would like to print each request:

use std::convert::Infallible;

use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Request, Response, Server};

async fn hello(req: Request<Body>) -> Result<Response<Body>, Infallible> {
    println!("{}", req.to_string()); // there is no .to_string() method but I would like something like this 
    Ok(Response::new(Body::from("Hello World!")))
}

#[tokio::main]
pub async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    pretty_env_logger::init();

    // For every connection, we must make a `Service` to handle all
    // incoming HTTP requests on said connection.
    let make_svc = make_service_fn(|_conn| {
        // This is the `Service` that will handle the connection.
        // `service_fn` is a helper to convert a function that
        // returns a Response into a `Service`.
        async { Ok::<_, Infallible>(service_fn(hello)) }
    });

    let addr = ([127, 0, 0, 1], 3000).into();

    let server = Server::bind(&addr).serve(make_svc);

    println!("Listening on http://{}", addr);

    server.await?;

    Ok(())
}
2 Answers

You probably want to look at the Uri definition from hyper. It has all of the parts of the request URL and implements Display, so you can easily format it.

It can be accessed from the request like such:

async fn hello(req: Request<Body>) -> Result<Response<Body>, Infallible> {
    println!("{}", req.uri());
    Ok(Response::new(Body::from("Hello World!")))
}

If you want to access the headers, you are going to have to iterate over them.

for (h_name, h_value) in req.headers() {
    println!("{}: {}", h_name, h_value.to_str().unwrap_or("Error: Non-visible ascii characters"));
}

You should be able to use the Debug representation of the Request in hello, it's implemented for any Request<T> where T: Debug https://github.com/hyperium/http/blob/c28945c6c6f99379b674a1e961a743c7752f2346/src/request.rs#L704-L715

If you change the print to println!("{:?}", req), you'll get most of the info, e.g. this for a GET request to your hello handler:

Request { method: GET, uri: /, version: HTTP/1.1, headers: {"host": "localhost:3000", "user-agent": "curl/7.68.0", "accept": "*/*"}, body: Body(Empty) }
Related