mirror of
https://github.com/tokio-rs/axum.git
synced 2025-01-01 08:56:15 +01:00
Don't inherit fallbacks when using Router::nest_service
(#1956)
This commit is contained in:
parent
db300efc33
commit
d1765d9a00
3 changed files with 9 additions and 81 deletions
|
@ -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])
|
type inference issues when calling `ServiceExt` methods on a `Router` ([#1835])
|
||||||
- **breaking:** Removed `axum::Server` as it was removed in hyper 1.0. Instead
|
- **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])
|
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
|
[#1664]: https://github.com/tokio-rs/axum/pull/1664
|
||||||
[#1751]: https://github.com/tokio-rs/axum/pull/1751
|
[#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
|
[#1835]: https://github.com/tokio-rs/axum/pull/1835
|
||||||
[#1850]: https://github.com/tokio-rs/axum/pull/1850
|
[#1850]: https://github.com/tokio-rs/axum/pull/1850
|
||||||
[#1868]: https://github.com/tokio-rs/axum/pull/1868
|
[#1868]: https://github.com/tokio-rs/axum/pull/1868
|
||||||
|
[#1956]: https://github.com/tokio-rs/axum/pull/1956
|
||||||
|
|
||||||
# 0.6.16 (18. April, 2023)
|
# 0.6.16 (18. April, 2023)
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ use std::{
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
};
|
};
|
||||||
use sync_wrapper::SyncWrapper;
|
|
||||||
use tower_layer::Layer;
|
use tower_layer::Layer;
|
||||||
use tower_service::Service;
|
use tower_service::Service;
|
||||||
|
|
||||||
|
@ -285,43 +284,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn call_with_state(
|
pub(crate) fn call_with_state(&mut self, req: Request, state: S) -> RouteFuture<Infallible> {
|
||||||
&mut self,
|
|
||||||
mut req: Request,
|
|
||||||
state: S,
|
|
||||||
) -> RouteFuture<Infallible> {
|
|
||||||
// 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(),
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
match self.path_router.call_with_state(req, state) {
|
match self.path_router.call_with_state(req, state) {
|
||||||
Ok(future) => future,
|
Ok(future) => future,
|
||||||
Err((mut req, state)) => {
|
Err((req, state)) => match self.fallback_router.call_with_state(req, state) {
|
||||||
let super_fallback = req
|
Ok(future) => future,
|
||||||
.extensions_mut()
|
Err((_req, _state)) => {
|
||||||
.remove::<SuperFallback<S>>()
|
unreachable!("the default fallback added in `Router::new` matches everything")
|
||||||
.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"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -662,8 +633,6 @@ impl<S> fmt::Debug for Endpoint<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SuperFallback<S>(SyncWrapper<PathRouter<S, true>>);
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[allow(warnings)]
|
#[allow(warnings)]
|
||||||
fn traits() {
|
fn traits() {
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use tower::ServiceExt;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::middleware::{map_request, map_response};
|
use crate::middleware::{map_request, map_response};
|
||||||
|
|
||||||
|
@ -166,48 +164,6 @@ async fn also_inherits_default_layered_fallback() {
|
||||||
assert_eq!(res.text().await, "outer");
|
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]
|
#[crate::test]
|
||||||
async fn nest_fallback_on_inner() {
|
async fn nest_fallback_on_inner() {
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
|
|
Loading…
Reference in a new issue