diff --git a/axum/src/routing/path_router.rs b/axum/src/routing/path_router.rs index e132f1dc..fd7d9ff1 100644 --- a/axum/src/routing/path_router.rs +++ b/axum/src/routing/path_router.rs @@ -357,7 +357,7 @@ where Endpoint::MethodRouter(method_router) => { Ok(method_router.call_with_state(req, state)) } - Endpoint::Route(route) => Ok(route.clone().call(req)), + Endpoint::Route(route) => Ok(route.clone().call_owned(req)), } } // explicitly handle all variants in case matchit adds diff --git a/axum/src/routing/route.rs b/axum/src/routing/route.rs index 25d41daf..3067e675 100644 --- a/axum/src/routing/route.rs +++ b/axum/src/routing/route.rs @@ -42,6 +42,12 @@ impl Route { ))) } + /// Variant of [`Route::call`] that takes ownership of the route to avoid cloning. + pub(crate) fn call_owned(self, req: Request) -> RouteFuture { + let req = req.map(Body::new); + RouteFuture::from_future(self.oneshot_inner_owned(req)) + } + pub(crate) fn oneshot_inner( &mut self, req: Request, diff --git a/axum/src/routing/tests/mod.rs b/axum/src/routing/tests/mod.rs index 83b2ed81..c7ae1f70 100644 --- a/axum/src/routing/tests/mod.rs +++ b/axum/src/routing/tests/mod.rs @@ -940,7 +940,7 @@ async fn state_isnt_cloned_too_much_in_layer() { client.get("/").await; - assert_eq!(state.count(), 4); + assert_eq!(state.count(), 3); } #[crate::test]