66
77use 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)
106106where
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" ) ;
0 commit comments