From ddc82395e8b5e869d3551de09990640c5ec3ee45 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Mon, 19 Feb 2018 14:27:36 -0800 Subject: [PATCH] try to remove trailing slash for normalize path handler --- src/application.rs | 2 +- src/handler.rs | 28 ++++++++++++++++++++-------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/application.rs b/src/application.rs index a4df1439..86cb2e5f 100644 --- a/src/application.rs +++ b/src/application.rs @@ -65,7 +65,7 @@ impl PipelineHandler for Inner { #[cfg(test)] impl HttpApplication { - #[cfg(test)] + #[cfg(test)] pub(crate) fn run(&mut self, req: HttpRequest) -> Reply { self.inner.borrow_mut().handle(req) } diff --git a/src/handler.rs b/src/handler.rs index 16de0583..72da14e2 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -379,6 +379,18 @@ impl Handler for NormalizePath { .body(Body::Empty); } } + + // try to remove trailing slash + if p.ends_with('/') { + let p = p.as_ref().trim_right_matches('/'); + if router.has_route(&p) { + let p = p.to_owned(); + let p = if !query.is_empty() { p + "?" + query } else { p }; + return HttpResponse::build(self.redirect) + .header(header::LOCATION, p.as_str()) + .body(Body::Empty); + } + } } } // append trailing slash @@ -478,16 +490,16 @@ mod tests { let params = vec![ ("/resource1/a/b", "", StatusCode::OK), ("//resource1//a//b", "/resource1/a/b", StatusCode::MOVED_PERMANENTLY), - ("//resource1//a//b/", "", StatusCode::NOT_FOUND), + ("//resource1//a//b/", "/resource1/a/b", StatusCode::MOVED_PERMANENTLY), ("///resource1//a//b", "/resource1/a/b", StatusCode::MOVED_PERMANENTLY), ("/////resource1/a///b", "/resource1/a/b", StatusCode::MOVED_PERMANENTLY), - ("/////resource1/a//b/", "", StatusCode::NOT_FOUND), + ("/////resource1/a//b/", "/resource1/a/b", StatusCode::MOVED_PERMANENTLY), ("/resource1/a/b?p=1", "", StatusCode::OK), ("//resource1//a//b?p=1", "/resource1/a/b?p=1", StatusCode::MOVED_PERMANENTLY), - ("//resource1//a//b/?p=1", "", StatusCode::NOT_FOUND), + ("//resource1//a//b/?p=1", "/resource1/a/b?p=1", StatusCode::MOVED_PERMANENTLY), ("///resource1//a//b?p=1", "/resource1/a/b?p=1", StatusCode::MOVED_PERMANENTLY), ("/////resource1/a///b?p=1", "/resource1/a/b?p=1", StatusCode::MOVED_PERMANENTLY), - ("/////resource1/a//b/?p=1", "", StatusCode::NOT_FOUND), + ("/////resource1/a//b/?p=1", "/resource1/a/b?p=1", StatusCode::MOVED_PERMANENTLY), ]; for (path, target, code) in params { let req = app.prepare_request(TestRequest::with_uri(path).finish()); @@ -519,9 +531,9 @@ mod tests { ("//resource2//a//b", "/resource2/a/b/", StatusCode::MOVED_PERMANENTLY), ("//resource2//a//b/", "/resource2/a/b/", StatusCode::MOVED_PERMANENTLY), ("///resource1//a//b", "/resource1/a/b", StatusCode::MOVED_PERMANENTLY), - ("///resource1//a//b/", "", StatusCode::NOT_FOUND), + ("///resource1//a//b/", "/resource1/a/b", StatusCode::MOVED_PERMANENTLY), ("/////resource1/a///b", "/resource1/a/b", StatusCode::MOVED_PERMANENTLY), - ("/////resource1/a///b/", "", StatusCode::NOT_FOUND), + ("/////resource1/a///b/", "/resource1/a/b", StatusCode::MOVED_PERMANENTLY), ("/resource2/a/b", "/resource2/a/b/", StatusCode::MOVED_PERMANENTLY), ("/resource2/a/b/", "", StatusCode::OK), ("//resource2//a//b", "/resource2/a/b/", StatusCode::MOVED_PERMANENTLY), @@ -535,9 +547,9 @@ mod tests { ("//resource2//a//b?p=1", "/resource2/a/b/?p=1", StatusCode::MOVED_PERMANENTLY), ("//resource2//a//b/?p=1", "/resource2/a/b/?p=1", StatusCode::MOVED_PERMANENTLY), ("///resource1//a//b?p=1", "/resource1/a/b?p=1", StatusCode::MOVED_PERMANENTLY), - ("///resource1//a//b/?p=1", "", StatusCode::NOT_FOUND), + ("///resource1//a//b/?p=1", "/resource1/a/b?p=1", StatusCode::MOVED_PERMANENTLY), ("/////resource1/a///b?p=1", "/resource1/a/b?p=1", StatusCode::MOVED_PERMANENTLY), - ("/////resource1/a///b/?p=1", "", StatusCode::NOT_FOUND), + ("/////resource1/a///b/?p=1", "/resource1/a/b?p=1", StatusCode::MOVED_PERMANENTLY), ("/resource2/a/b?p=1", "/resource2/a/b/?p=1", StatusCode::MOVED_PERMANENTLY), ("//resource2//a//b?p=1", "/resource2/a/b/?p=1", StatusCode::MOVED_PERMANENTLY), ("//resource2//a//b/?p=1", "/resource2/a/b/?p=1", StatusCode::MOVED_PERMANENTLY),