1

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(())
}
Max888
  • 3,089
  • 24
  • 55

2 Answers2

1

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"));
}
Adam Comer
  • 492
  • 2
  • 10
1

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) }
sebpuetz
  • 2,430
  • 1
  • 7
  • 15
  • Thanks, while I would still prefer to have access to the raw unparsed requested, this certainly saves me from having to write something similar. Would much prefer the raw request though as it will definitely contain all info and is easier to read (line breaks etc). I accept you answer unless it turns out it is possible to get the raw request string. – Max888 Jan 10 '22 at 23:28