Skip to content

Commit 3497e5d

Browse files
authored
Update TLS examples to use better HTTP->HTTPS redirect (#2792)
1 parent 33b353d commit 3497e5d

File tree

2 files changed

+30
-10
lines changed

2 files changed

+30
-10
lines changed

examples/tls-graceful-shutdown/src/main.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
77
use axum::{
88
handler::HandlerWithoutStateExt,
9-
http::{StatusCode, Uri},
9+
http::{uri::Authority, StatusCode, Uri},
1010
response::Redirect,
1111
routing::get,
1212
BoxError, Router,
@@ -106,7 +106,7 @@ async fn redirect_http_to_https<F>(ports: Ports, signal: F)
106106
where
107107
F: Future<Output = ()> + Send + 'static,
108108
{
109-
fn make_https(host: String, uri: Uri, ports: Ports) -> Result<Uri, BoxError> {
109+
fn make_https(host: &str, uri: Uri, https_port: u16) -> Result<Uri, BoxError> {
110110
let mut parts = uri.into_parts();
111111

112112
parts.scheme = Some(axum::http::uri::Scheme::HTTPS);
@@ -115,14 +115,24 @@ where
115115
parts.path_and_query = Some("/".parse().unwrap());
116116
}
117117

118-
let https_host = host.replace(&ports.http.to_string(), &ports.https.to_string());
119-
parts.authority = Some(https_host.parse()?);
118+
let authority: Authority = host.parse()?;
119+
let bare_host = match authority.port() {
120+
Some(port_struct) => authority
121+
.as_str()
122+
.strip_suffix(port_struct.as_str())
123+
.unwrap()
124+
.strip_suffix(':')
125+
.unwrap(), // if authority.port() is Some(port) then we can be sure authority ends with :{port}
126+
None => authority.as_str(),
127+
};
128+
129+
parts.authority = Some(format!("{bare_host}:{https_port}").parse()?);
120130

121131
Ok(Uri::from_parts(parts)?)
122132
}
123133

124134
let redirect = move |Host(host): Host, uri: Uri| async move {
125-
match make_https(host, uri, ports) {
135+
match make_https(&host, uri, ports.https) {
126136
Ok(uri) => Ok(Redirect::permanent(&uri.to_string())),
127137
Err(error) => {
128138
tracing::warn!(%error, "failed to convert URI to HTTPS");

examples/tls-rustls/src/main.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
use axum::{
1010
handler::HandlerWithoutStateExt,
11-
http::{StatusCode, Uri},
11+
http::{uri::Authority, StatusCode, Uri},
1212
response::Redirect,
1313
routing::get,
1414
BoxError, Router,
@@ -72,7 +72,7 @@ async fn handler() -> &'static str {
7272

7373
#[allow(dead_code)]
7474
async fn redirect_http_to_https(ports: Ports) {
75-
fn make_https(host: String, uri: Uri, ports: Ports) -> Result<Uri, BoxError> {
75+
fn make_https(host: &str, uri: Uri, https_port: u16) -> Result<Uri, BoxError> {
7676
let mut parts = uri.into_parts();
7777

7878
parts.scheme = Some(axum::http::uri::Scheme::HTTPS);
@@ -81,14 +81,24 @@ async fn redirect_http_to_https(ports: Ports) {
8181
parts.path_and_query = Some("/".parse().unwrap());
8282
}
8383

84-
let https_host = host.replace(&ports.http.to_string(), &ports.https.to_string());
85-
parts.authority = Some(https_host.parse()?);
84+
let authority: Authority = host.parse()?;
85+
let bare_host = match authority.port() {
86+
Some(port_struct) => authority
87+
.as_str()
88+
.strip_suffix(port_struct.as_str())
89+
.unwrap()
90+
.strip_suffix(':')
91+
.unwrap(), // if authority.port() is Some(port) then we can be sure authority ends with :{port}
92+
None => authority.as_str(),
93+
};
94+
95+
parts.authority = Some(format!("{bare_host}:{https_port}").parse()?);
8696

8797
Ok(Uri::from_parts(parts)?)
8898
}
8999

90100
let redirect = move |Host(host): Host, uri: Uri| async move {
91-
match make_https(host, uri, ports) {
101+
match make_https(&host, uri, ports.https) {
92102
Ok(uri) => Ok(Redirect::permanent(&uri.to_string())),
93103
Err(error) => {
94104
tracing::warn!(%error, "failed to convert URI to HTTPS");

0 commit comments

Comments
 (0)