1

Trying to get the full request URI (scheme + authority + path)

I have found the discussion: https://github.com/tokio-rs/axum/discussions/1149 which says that Request.uri() should have it. So I tried the following:

use axum::body::Body;
use axum::http::Request;
use axum::routing::get;
use axum::Router;

async fn handler(req: Request<Body>) -> &'static str {
    println!("The request is: {}", req.uri());
    println!("The request is: {}", req.uri().scheme_str().unwrap());
    println!("The request is: {}", req.uri().authority().unwrap());

    "Hello world"
}

#[tokio::main]
async fn main() {
    let app = Router::new().route("/test", get(handler));

    axum::Server::bind(&"0.0.0.0:8080".parse().unwrap())
        .serve(app.into_make_service())
        .await
        .unwrap();
}

And run curl -v "http://localhost:8080/test" but I get:

The request is: /test
thread 'tokio-runtime-worker' panicked at 'called `Option::unwrap()` on a `None` value', src/main.rs:8:59

It seems like it only contains the path.

I also found the other discussion: https://github.com/tokio-rs/axum/discussions/858 which suggests that axum::http::Uri should be able to extract all the details, but I get the same issue:

use axum::http::Uri;
use axum::routing::get;
use axum::Router;

async fn handler(uri: Uri) -> &'static str {
    println!("The request is: {}", uri);
    println!("The request is: {}", uri.scheme_str().unwrap());
    println!("The request is: {}", uri.authority().unwrap());

    "Hello world"
}

#[tokio::main]
async fn main() {
    let app = Router::new().route("/test", get(handler));

    axum::Server::bind(&"0.0.0.0:8080".parse().unwrap())
        .serve(app.into_make_service())
        .await
        .unwrap();
}

curl -v "http://localhost:8080/test"

The request is: /test
thread 'tokio-runtime-worker' panicked at 'called `Option::unwrap()` on a `None` value', src/main.rs:7:53
> cargo -V
cargo 1.68.0-nightly (2381cbdb4 2022-12-23)

> rustc --version
rustc 1.68.0-nightly (ad8ae0504 2022-12-29)

Cargo.toml

[package]
name = "axum_test"
version = "0.1.0"
edition = "2021"

[dependencies]
axum = "0.6.10"
tokio = { version = "1.26.0", features = ["macros", "rt-multi-thread"] }
mepmerp
  • 701
  • 1
  • 9
  • 16
  • what about don't unwrap ? I don't understand your question. – Stargateur Mar 05 '23 at 02:56
  • I have a basic local server running on localhost on port 8080. And I make a request to my server at `http://127.0.0.1/test`. How can I get axum to give me the full request URL, which is expected to be `http://127.0.0.1/test`. Using both `Request.uri()` and `axum::http::Uri` only gives me the path `/test` and not `http://127.0.0.1/test`. Axum should be able to give me the full request URI, right? I don't want to hardcode the values `http`, `127.0.0.1`, and `8080` to reconstruct the whole URL. It makes it less flexible. I briefly used actix-web and I was able to get the full request URL – mepmerp Mar 05 '23 at 03:37
  • its look axium doesn't give you that information, I suggest you open an issue – Stargateur Mar 05 '23 at 10:51
  • https://github.com/tokio-rs/axum/blob/main/examples/http-proxy/src/main.rs – Stargateur Mar 05 '23 at 10:58

1 Answers1

0

The Uri in Request only provides path. You could use the Host extractor:

use axum::extract::Host;
use axum::http::Request;

#[tokio::main]
async fn main() {
    // ...
    let app = Router::new()
        .route(
            "/",
            any(|Host(hostname): Host, request: Request<Body>| async move {
                format!("Hi {hostname}")
            }),
        )
        .layer(Extension(state));
    // ...
}
Tody.Lu
  • 915
  • 9
  • 24