From 1614ef7a228607242de578f499806fefb489d6bc Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Fri, 4 Mar 2022 09:28:44 +0100 Subject: [PATCH] Fix inconsistent double slash when nesting routes (#824) --- axum/CHANGELOG.md | 3 +++ axum/src/routing/mod.rs | 2 ++ axum/src/routing/tests/nest.rs | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/axum/CHANGELOG.md b/axum/CHANGELOG.md index dd10a6d2..e9d0fc67 100644 --- a/axum/CHANGELOG.md +++ b/axum/CHANGELOG.md @@ -60,6 +60,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **breaking:** `AddExtensionLayer` has been removed. Use `Extension` instead. It now implements `tower::Layer` ([#807]) - **breaking:** `AddExtension` has been moved from the root module to `middleware` +- **breaking:** `.nest("/foo/", Router::new().route("/bar", _))` now does the right thing and + results in a route at `/foo/bar` instead of `/foo//bar` ([#824]) - **breaking:** Routes are now required to start with `/`. Previously routes such as `:foo` would be accepted but most likely result in bugs ([#823]) - **fixed:** Set `Allow` header when responding with `405 Method Not Allowed` ([#733]) @@ -85,6 +87,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#807]: https://github.com/tokio-rs/axum/pull/807 [#819]: https://github.com/tokio-rs/axum/pull/819 [#823]: https://github.com/tokio-rs/axum/pull/823 +[#824]: https://github.com/tokio-rs/axum/pull/824 # 0.4.4 (13. January, 2022) diff --git a/axum/src/routing/mod.rs b/axum/src/routing/mod.rs index 642febf3..59c2d6c6 100644 --- a/axum/src/routing/mod.rs +++ b/axum/src/routing/mod.rs @@ -215,6 +215,8 @@ where path.into() } else if path == "/" { (&*nested_path).into() + } else if let Some(path) = path.strip_suffix('/') { + format!("{}{}", path, nested_path).into() } else { format!("{}{}", path, nested_path).into() }; diff --git a/axum/src/routing/tests/nest.rs b/axum/src/routing/tests/nest.rs index 058e9123..569c8785 100644 --- a/axum/src/routing/tests/nest.rs +++ b/axum/src/routing/tests/nest.rs @@ -345,3 +345,37 @@ async fn outer_middleware_still_see_whole_url() { ); assert_eq!(client.get("/one/two").send().await.text().await, "/one/two"); } + +macro_rules! nested_route_test { + ( + $name:ident, + nest = $nested_path:literal, + route = $route_path:literal, + expected = $expected_path:literal $(,)? + ) => { + #[tokio::test] + async fn $name() { + let inner = Router::new().route($route_path, get(|| async {})); + let app = Router::new().nest($nested_path, inner); + let client = TestClient::new(app); + assert_eq!( + client.get($expected_path).send().await.status(), + StatusCode::OK + ); + } + }; +} + +// test cases taken from https://github.com/tokio-rs/axum/issues/714#issuecomment-1058144460 +nested_route_test!(nest_1, nest = "", route = "/", expected = "/"); +nested_route_test!(nest_2, nest = "", route = "/a", expected = "/a"); +nested_route_test!(nest_3, nest = "", route = "/a/", expected = "/a/"); +nested_route_test!(nest_4, nest = "/", route = "/", expected = "/"); +nested_route_test!(nest_5, nest = "/", route = "/a", expected = "/a"); +nested_route_test!(nest_6, nest = "/", route = "/a/", expected = "/a/"); +nested_route_test!(nest_7, nest = "/a", route = "/", expected = "/a"); +nested_route_test!(nest_8, nest = "/a", route = "/a", expected = "/a/a"); +nested_route_test!(nest_9, nest = "/a", route = "/a/", expected = "/a/a/"); +nested_route_test!(nest_11, nest = "/a/", route = "/", expected = "/a/"); +nested_route_test!(nest_12, nest = "/a/", route = "/a", expected = "/a/a"); +nested_route_test!(nest_13, nest = "/a/", route = "/a/", expected = "/a/a/");