diff --git a/axum/CHANGELOG.md b/axum/CHANGELOG.md index 9bb555bbdf..a6d827e3e0 100644 --- a/axum/CHANGELOG.md +++ b/axum/CHANGELOG.md @@ -50,6 +50,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 type inference issues when calling `ServiceExt` methods on a `Router` ([#1835]) - **breaking:** Removed `axum::Server` as it was removed in hyper 1.0. Instead use `axum::serve(listener, service)` or hyper/hyper-util for more configuration options ([#1868]) +- **breaking:** Only inherit fallbacks for routers nested with `Router::nest`. + Routers nested with `Router::nest_service` will no longer inherit fallbacks ([#1956]) [#1664]: https://github.com/tokio-rs/axum/pull/1664 [#1751]: https://github.com/tokio-rs/axum/pull/1751 @@ -58,6 +60,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#1835]: https://github.com/tokio-rs/axum/pull/1835 [#1850]: https://github.com/tokio-rs/axum/pull/1850 [#1868]: https://github.com/tokio-rs/axum/pull/1868 +[#1956]: https://github.com/tokio-rs/axum/pull/1956 # 0.6.16 (18. April, 2023) diff --git a/axum/src/routing/mod.rs b/axum/src/routing/mod.rs index 12b66ac6e7..6a5f68878a 100644 --- a/axum/src/routing/mod.rs +++ b/axum/src/routing/mod.rs @@ -19,7 +19,6 @@ use std::{ marker::PhantomData, task::{Context, Poll}, }; -use sync_wrapper::SyncWrapper; use tower_layer::Layer; use tower_service::Service; @@ -285,43 +284,15 @@ where } } - pub(crate) fn call_with_state( - &mut self, - mut req: Request, - state: S, - ) -> RouteFuture { - // required for opaque routers to still inherit the fallback - // TODO(david): remove this feature in 0.7 - if !self.default_fallback { - req.extensions_mut().insert(SuperFallback(SyncWrapper::new( - self.fallback_router.clone(), - ))); - } - + pub(crate) fn call_with_state(&mut self, req: Request, state: S) -> RouteFuture { match self.path_router.call_with_state(req, state) { Ok(future) => future, - Err((mut req, state)) => { - let super_fallback = req - .extensions_mut() - .remove::>() - .map(|SuperFallback(path_router)| path_router.into_inner()); - - if let Some(mut super_fallback) = super_fallback { - return super_fallback - .call_with_state(req, state) - .unwrap_or_else(|_| unreachable!()); - } - - match self.fallback_router.call_with_state(req, state) { - Ok(future) => future, - Err((_req, _state)) => { - unreachable!( - "the default fallback added in `Router::new` \ - matches everything" - ) - } + Err((req, state)) => match self.fallback_router.call_with_state(req, state) { + Ok(future) => future, + Err((_req, _state)) => { + unreachable!("the default fallback added in `Router::new` matches everything") } - } + }, } } @@ -662,8 +633,6 @@ impl fmt::Debug for Endpoint { } } -struct SuperFallback(SyncWrapper>); - #[test] #[allow(warnings)] fn traits() { diff --git a/axum/src/routing/tests/fallback.rs b/axum/src/routing/tests/fallback.rs index 6833dad398..e527fe6f86 100644 --- a/axum/src/routing/tests/fallback.rs +++ b/axum/src/routing/tests/fallback.rs @@ -1,5 +1,3 @@ -use tower::ServiceExt; - use super::*; use crate::middleware::{map_request, map_response}; @@ -166,48 +164,6 @@ async fn also_inherits_default_layered_fallback() { assert_eq!(res.text().await, "outer"); } -#[crate::test] -async fn fallback_inherited_into_nested_router_service() { - let inner = Router::new() - .route( - "/bar", - get(|State(state): State<&'static str>| async move { state }), - ) - .with_state("inner"); - - // with a different state - let app = Router::new() - .nest_service("/foo", inner) - .fallback(outer_fallback); - - let client = TestClient::new(app); - let res = client.get("/foo/not-found").send().await; - assert_eq!(res.status(), StatusCode::NOT_FOUND); - assert_eq!(res.text().await, "outer"); -} - -#[crate::test] -async fn fallback_inherited_into_nested_opaque_service() { - let inner = Router::new() - .route( - "/bar", - get(|State(state): State<&'static str>| async move { state }), - ) - .with_state("inner") - // even if the service is made more opaque it should still inherit the fallback - .boxed_clone(); - - // with a different state - let app = Router::new() - .nest_service("/foo", inner) - .fallback(outer_fallback); - - let client = TestClient::new(app); - let res = client.get("/foo/not-found").send().await; - assert_eq!(res.status(), StatusCode::NOT_FOUND); - assert_eq!(res.text().await, "outer"); -} - #[crate::test] async fn nest_fallback_on_inner() { let app = Router::new()