diff --git a/crates/core/src/routing/filters/path.rs b/crates/core/src/routing/filters/path.rs index 6183558fb..cfc8f27b2 100644 --- a/crates/core/src/routing/filters/path.rs +++ b/crates/core/src/routing/filters/path.rs @@ -1064,21 +1064,15 @@ impl PathFilter { /// Detect is that path is match. pub fn detect(&self, state: &mut PathState) -> bool { let original_cursor = state.cursor; - #[cfg(feature = "matched-path")] - let original_matched_parts_len = state.matched_parts.len(); for ps in &self.path_wisps { let row = state.cursor.0; if ps.detect(state) { if row == state.cursor.0 && row != state.parts.len() { state.cursor = original_cursor; - #[cfg(feature = "matched-path")] - state.matched_parts.truncate(original_matched_parts_len); return false; } } else { state.cursor = original_cursor; - #[cfg(feature = "matched-path")] - state.matched_parts.truncate(original_matched_parts_len); return false; } } diff --git a/crates/core/src/routing/mod.rs b/crates/core/src/routing/mod.rs index fa7accc96..cc9d4c479 100644 --- a/crates/core/src/routing/mod.rs +++ b/crates/core/src/routing/mod.rs @@ -442,4 +442,68 @@ mod tests { .contains("404: Not Found")); assert_eq!(access(&service, "localhost").await, "Hello World"); } + + #[tokio::test] + async fn test_matched_path() { + #[handler] + async fn alice1(req: &mut Request) { + assert_eq!(req.matched_path(), "open/alice1"); + } + #[handler] + async fn bob1(req: &mut Request) { + assert_eq!(req.matched_path(), "open/alice1/bob1"); + } + + #[handler] + async fn alice2(req: &mut Request) { + assert_eq!(req.matched_path(), "open/alice2"); + } + #[handler] + async fn bob2(req: &mut Request) { + assert_eq!(req.matched_path(), "open/alice2/bob2"); + } + + #[handler] + async fn alice3(req: &mut Request) { + assert_eq!(req.matched_path(), "alice3"); + } + #[handler] + async fn bob3(req: &mut Request) { + assert_eq!(req.matched_path(), "alice3/bob3"); + } + + let router = Router::new() + .push( + Router::with_path("open").push( + Router::with_path("alice1") + .get(alice1) + .push(Router::with_path("bob1").get(bob1)), + ), + ) + .push( + Router::with_path("open").push( + Router::with_path("alice2") + .get(alice2) + .push(Router::with_path("bob2").get(bob2)), + ), + ) + .push( + Router::with_path("alice3") + .get(alice3) + .push(Router::with_path("bob3").get(bob3)), + ); + let service = Service::new(router); + + async fn access(service: &Service, path: &str) { + TestClient::get(format!("http://127.0.0.1/{}", path)) + .send(service) + .await; + } + access(&service, "/open/alice1").await; + access(&service, "/open/alice1/bob1").await; + access(&service, "/open/alice2").await; + access(&service, "/open/alice2/bob2").await; + access(&service, "/alice3").await; + access(&service, "/alice1/bob3").await; + } } diff --git a/crates/core/src/routing/router.rs b/crates/core/src/routing/router.rs index c09ec614c..f29778fe7 100644 --- a/crates/core/src/routing/router.rs +++ b/crates/core/src/routing/router.rs @@ -93,6 +93,8 @@ impl Router { } if !self.routers.is_empty() { let original_cursor = path_state.cursor; + #[cfg(feature = "matched-path")] + let original_matched_parts_len = path_state.matched_parts.len(); for child in &self.routers { if let Some(dm) = child.detect(req, path_state).await { return Some(DetectMatched { @@ -100,6 +102,10 @@ impl Router { goal: dm.goal.clone(), }); } else { + #[cfg(feature = "matched-path")] + path_state + .matched_parts + .truncate(original_matched_parts_len); path_state.cursor = original_cursor; } }