Axum OriginalUri returns None for scheme, host, port

I have a route in Axum that generates html that gets sent to the client, which contains a picture on the same server in another route:

The function the route is bound to is below, together with what I have been trying so far.
Currently, I have set scheme, host and port set to fixed values. However, I want it to pick up these from the client request, so that any client GET request that makes it to this route will be able to pick up the image:

async fn plot_handler_html(OriginalUri(url): OriginalUri) -> axum::response::Html<String> {
 let scheme = url.scheme_str().unwrap_or("unknown");
 let host = url.host().unwrap_or("unknown");
 let port = if let Some(port) = url.port() { format!(":{}", port) } else { String::from(":unknown") };
 let server_spec = format!("{}://{}{}", scheme, host, port);
 format!(r#"
 <!doctype html>
 <html>
  <body>
   <img src="{server_spec}/img">
  </body>
 </html>
 "#).into()
}

The problem here is that the response is:

โžœ curl http://localhost:3000

 <!doctype html>
 <html>
  <body>
   <img src="unknown://unknown:unknown/img">
  </body>
 </html>

For which I would expect, and hope to accomplish with your help to be http://localhost:3000/img as image source.

Of course when starting it from localhost it's easy to just fill out the host yourself. However, if this is started from 0.0.0.0 in the future, it will listen on all networks on the set port, which makes it hard to determine the host that the Axum client is using, and requires changing and recompilation, which is not handy.

Link to full code: Code shared from the Rust Playground ยท GitHub

You can see in the docs that OriginalUri returns the full path for the route, it doesn't include the host nor the scheme.

2 Likes

Yes, I read that, but I assumed that was about Uri, and that OriginalUri would include these. Otherwise these methods do not make sense?

Those methods come the Uri model, ak.a. from dereferencing OriginalUri into Uri. I agree that they don't make sense on OriginalUri otherwise.

As for a solution for getting a full Uri, I would recommend to use a configuration system where you can hard-code http://localhost:3000 for development and https://mysite.com for production.

Are you aware of any way to fetch the full web server client request in any way to obtain method, server and port of the request, or another way to embed to image into the html?

You can use Request to extract the whole request, including the uri.

By the way, relative links work in html, i.e

<img src="/img">

should load localhost:3000/img.

1 Like

Dang! That's it! By not specifying the host, I can quit trying to get the scheme, hostname and port and it does exactly what I need!!
Thank you!

1 Like

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.