fix MatchedPath with Routers nested with nest_service

This commit is contained in:
David Pedersen
2022-06-29 22:48:44 +02:00
parent fb5219f9cd
commit 657a0893b5
3 changed files with 36 additions and 3 deletions
+16
View File
@@ -178,4 +178,20 @@ mod tests {
),
);
}
#[tokio::test]
async fn nested_opaque_routers_append_to_matched_path() {
let app = Router::new().nest_service(
"/:a",
Router::new().route(
"/:b",
get(|path: MatchedPath| async move { path.as_str().to_owned() }),
),
);
let client = TestClient::new(app);
let res = client.get("/foo/bar").send().await;
assert_eq!(res.text().await, "/:a/:b");
}
}
+19 -2
View File
@@ -98,6 +98,7 @@ impl<B> fmt::Debug for Router<B> {
}
pub(crate) const NEST_TAIL_PARAM: &str = "__private__axum_nest_tail_param";
const NEST_TAIL_PARAM_CAPTURE: &str = "/*__private__axum_nest_tail_param";
impl<B> Router<B>
where
@@ -416,8 +417,24 @@ where
#[cfg(feature = "matched-path")]
if let Some(matched_path) = self.node.route_id_to_path.get(&id) {
req.extensions_mut()
.insert(crate::extract::MatchedPath(Arc::clone(matched_path)));
use crate::extract::MatchedPath;
let matched_path = if let Some(previous) = req.extensions_mut().get::<MatchedPath>() {
// a previous `MatchedPath` might exist if we're inside a nested Router
let previous = if let Some(previous) =
previous.as_str().strip_suffix(NEST_TAIL_PARAM_CAPTURE)
{
previous
} else {
previous.as_str()
};
let matched_path = format!("{}{}", previous, matched_path);
matched_path.into()
} else {
Arc::clone(matched_path)
};
req.extensions_mut().insert(MatchedPath(matched_path));
} else {
#[cfg(debug_assertions)]
panic!("should always have a matched path for a route id");
+1 -1
View File
@@ -414,7 +414,7 @@ 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_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/");