diff --git a/tower-http/src/normalize_path.rs b/tower-http/src/normalize_path.rs index 19c89a82..91ee5b92 100644 --- a/tower-http/src/normalize_path.rs +++ b/tower-http/src/normalize_path.rs @@ -108,21 +108,15 @@ where } fn normalize_trailing_slash(uri: &mut Uri) { - if !uri.path().ends_with('/') { + if !uri.path().ends_with('/') && !uri.path().starts_with("//") { return; } - let new_path = uri.path().trim_end_matches('/'); + let new_path = format!("/{}", uri.path().trim_matches('/')); let mut parts = uri.clone().into_parts(); let new_path_and_query = if let Some(path_and_query) = &parts.path_and_query { - let new_path = if new_path.is_empty() { - "/" - } else { - new_path.into() - }; - let new_path_and_query = if let Some(query) = path_and_query.query() { Cow::Owned(format!("{}?{}", new_path, query)) } else { @@ -218,4 +212,18 @@ mod tests { normalize_trailing_slash(&mut uri); assert_eq!(uri, "/?a=a"); } + + #[test] + fn removes_multiple_preceding_slashes_even_with_query() { + let mut uri = "///foo//?a=a".parse::().unwrap(); + normalize_trailing_slash(&mut uri); + assert_eq!(uri, "/foo?a=a"); + } + + #[test] + fn removes_multiple_preceding_slashes() { + let mut uri = "///foo".parse::().unwrap(); + normalize_trailing_slash(&mut uri); + assert_eq!(uri, "/foo"); + } }