Skip to content

Commit 4788a44

Browse files
authored
Fix path normalization of index route (#347)
Previously, `normalize_path` on `/` would result in an empty string, causing routers to return 404 on the index route. Fix this by defaulting to `/` if the resultant path would be empty. Fixes #318.
1 parent 9bb6d62 commit 4788a44

File tree

1 file changed

+33
-6
lines changed

1 file changed

+33
-6
lines changed

tower-http/src/normalize_path.rs

+33-6
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,12 @@ where
102102
}
103103

104104
fn call(&mut self, mut req: Request<ReqBody>) -> Self::Future {
105-
remove_trailing_slash(req.uri_mut());
105+
normalize_trailing_slash(req.uri_mut());
106106
self.inner.call(req)
107107
}
108108
}
109109

110-
fn remove_trailing_slash(uri: &mut Uri) {
110+
fn normalize_trailing_slash(uri: &mut Uri) {
111111
if !uri.path().ends_with('/') {
112112
return;
113113
}
@@ -117,6 +117,12 @@ fn remove_trailing_slash(uri: &mut Uri) {
117117
let mut parts = uri.clone().into_parts();
118118

119119
let new_path_and_query = if let Some(path_and_query) = &parts.path_and_query {
120+
let new_path = if new_path.is_empty() {
121+
"/"
122+
} else {
123+
new_path.into()
124+
};
125+
120126
let new_path_and_query = if let Some(query) = path_and_query.query() {
121127
Cow::Owned(format!("{}?{}", new_path, query))
122128
} else {
@@ -167,28 +173,49 @@ mod tests {
167173
#[test]
168174
fn is_noop_if_no_trailing_slash() {
169175
let mut uri = "/foo".parse::<Uri>().unwrap();
170-
remove_trailing_slash(&mut uri);
176+
normalize_trailing_slash(&mut uri);
171177
assert_eq!(uri, "/foo");
172178
}
173179

174180
#[test]
175181
fn maintains_query() {
176182
let mut uri = "/foo/?a=a".parse::<Uri>().unwrap();
177-
remove_trailing_slash(&mut uri);
183+
normalize_trailing_slash(&mut uri);
178184
assert_eq!(uri, "/foo?a=a");
179185
}
180186

181187
#[test]
182188
fn removes_multiple_trailing_slashes() {
183189
let mut uri = "/foo////".parse::<Uri>().unwrap();
184-
remove_trailing_slash(&mut uri);
190+
normalize_trailing_slash(&mut uri);
185191
assert_eq!(uri, "/foo");
186192
}
187193

188194
#[test]
189195
fn removes_multiple_trailing_slashes_even_with_query() {
190196
let mut uri = "/foo////?a=a".parse::<Uri>().unwrap();
191-
remove_trailing_slash(&mut uri);
197+
normalize_trailing_slash(&mut uri);
192198
assert_eq!(uri, "/foo?a=a");
193199
}
200+
201+
#[test]
202+
fn is_noop_on_index() {
203+
let mut uri = "/".parse::<Uri>().unwrap();
204+
normalize_trailing_slash(&mut uri);
205+
assert_eq!(uri, "/");
206+
}
207+
208+
#[test]
209+
fn removes_multiple_trailing_slashes_on_index() {
210+
let mut uri = "////".parse::<Uri>().unwrap();
211+
normalize_trailing_slash(&mut uri);
212+
assert_eq!(uri, "/");
213+
}
214+
215+
#[test]
216+
fn removes_multiple_trailing_slashes_on_index_even_with_query() {
217+
let mut uri = "////?a=a".parse::<Uri>().unwrap();
218+
normalize_trailing_slash(&mut uri);
219+
assert_eq!(uri, "/?a=a");
220+
}
194221
}

0 commit comments

Comments
 (0)