From 7f8073233a4b9230f5bf9bdd04cbc5e931553cb5 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 15 Sep 2020 11:32:31 +0100 Subject: [PATCH] fix trimming to inaccessible root path (#1678) --- CHANGES.md | 4 ++++ src/middleware/normalize.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index aadf627bc..3379875ec 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,10 @@ # Changes ## Unreleased - 2020-xx-xx +### Fixed +* `NormalizePath` when used with `TrailingSlash::Trim` no longer trims the root path "/". [#1678] + +[#1678]: https://github.com/actix/actix-web/pull/1678 ## 3.0.1 - 2020-09-13 diff --git a/src/middleware/normalize.rs b/src/middleware/normalize.rs index 1b6894796..8452c9083 100644 --- a/src/middleware/normalize.rs +++ b/src/middleware/normalize.rs @@ -79,6 +79,7 @@ where } } +#[doc(hidden)] pub struct NormalizePathNormalization { service: S, merge_slash: Regex, @@ -113,6 +114,10 @@ where // normalize multiple /'s to one / let path = self.merge_slash.replace_all(&path, "/"); + // Ensure root paths are still resolvable. If resulting path is blank after previous step + // it means the path was one or more slashes. Reduce to single slash. + let path = if path.is_empty() { "/" } else { path.as_ref() }; + // Check whether the path has been changed // // This check was previously implemented as string length comparison @@ -158,10 +163,23 @@ mod tests { let mut app = init_service( App::new() .wrap(NormalizePath::default()) + .service(web::resource("/").to(HttpResponse::Ok)) .service(web::resource("/v1/something/").to(HttpResponse::Ok)), ) .await; + let req = TestRequest::with_uri("/").to_request(); + let res = call_service(&mut app, req).await; + assert!(res.status().is_success()); + + let req = TestRequest::with_uri("/?query=test").to_request(); + let res = call_service(&mut app, req).await; + assert!(res.status().is_success()); + + let req = TestRequest::with_uri("///").to_request(); + let res = call_service(&mut app, req).await; + assert!(res.status().is_success()); + let req = TestRequest::with_uri("/v1//something////").to_request(); let res = call_service(&mut app, req).await; assert!(res.status().is_success()); @@ -184,10 +202,24 @@ mod tests { let mut app = init_service( App::new() .wrap(NormalizePath(TrailingSlash::Trim)) + .service(web::resource("/").to(HttpResponse::Ok)) .service(web::resource("/v1/something").to(HttpResponse::Ok)), ) .await; + // root paths should still work + let req = TestRequest::with_uri("/").to_request(); + let res = call_service(&mut app, req).await; + assert!(res.status().is_success()); + + let req = TestRequest::with_uri("/?query=test").to_request(); + let res = call_service(&mut app, req).await; + assert!(res.status().is_success()); + + let req = TestRequest::with_uri("///").to_request(); + let res = call_service(&mut app, req).await; + assert!(res.status().is_success()); + let req = TestRequest::with_uri("/v1/something////").to_request(); let res = call_service(&mut app, req).await; assert!(res.status().is_success());