mirror of
https://github.com/tokio-rs/axum.git
synced 2026-09-09 00:00:12 +02:00
Add method filtering to route_with_tsr (#3586)
This commit is contained in:
@@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
(never returned `Err`) and be an uninhabited type if `with_graceful_shutdown` is not used
|
||||
(because it was already never terminating if that method wasn't used) ([#3601])
|
||||
- **added:** New `ListenerExt::limit_connections` allows limiting concurrent `axum::serve` connections ([#3489])
|
||||
- **added:** `MethodRouter::method_filter` ([#3586])
|
||||
- **changed:** `serve` has an additional generic argument and can now work with any response body
|
||||
type, not just `axum::body::Body` ([#3205])
|
||||
|
||||
@@ -24,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
[#3478]: https://github.com/tokio-rs/axum/pull/3478
|
||||
[#3601]: https://github.com/tokio-rs/axum/pull/3601
|
||||
[#3489]: https://github.com/tokio-rs/axum/pull/3489
|
||||
[#3586]: https://github.com/tokio-rs/axum/pull/3586
|
||||
|
||||
# 0.8.8
|
||||
|
||||
|
||||
@@ -660,6 +660,54 @@ where
|
||||
self
|
||||
}
|
||||
|
||||
/// Get a [`MethodFilter`] for the methods that this `MethodRouter` has
|
||||
/// custom code for.
|
||||
///
|
||||
/// Note that `MethodRouter`'s [`Service`] implementation never fails (it
|
||||
/// always creates an HTTP response) based on which HTTP method was used.
|
||||
/// However, the information which methods have the default behavior of
|
||||
/// returning HTTP 405 is stored, and can be queried with this method.
|
||||
///
|
||||
/// Returns `None` if the `MethodRouter` was constructed with [`any`] or
|
||||
/// has had a [`fallback`][Self::fallback] set.
|
||||
pub fn method_filter(&self) -> Option<MethodFilter> {
|
||||
let Self {
|
||||
get,
|
||||
head,
|
||||
delete,
|
||||
options,
|
||||
patch,
|
||||
post,
|
||||
put,
|
||||
trace,
|
||||
connect,
|
||||
fallback,
|
||||
allow_header: _,
|
||||
} = self;
|
||||
|
||||
if !fallback.is_default() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let filter = [
|
||||
(get, MethodFilter::GET),
|
||||
(head, MethodFilter::HEAD),
|
||||
(delete, MethodFilter::DELETE),
|
||||
(options, MethodFilter::OPTIONS),
|
||||
(patch, MethodFilter::PATCH),
|
||||
(post, MethodFilter::POST),
|
||||
(put, MethodFilter::PUT),
|
||||
(trace, MethodFilter::TRACE),
|
||||
(connect, MethodFilter::CONNECT),
|
||||
]
|
||||
.into_iter()
|
||||
.filter_map(|(ep, f)| ep.is_some().then_some(f))
|
||||
.reduce(MethodFilter::or)
|
||||
.expect("can't create a MethodRouter with all-default handlers");
|
||||
|
||||
Some(filter)
|
||||
}
|
||||
|
||||
/// Add a fallback [`Handler`] if no custom one has been provided.
|
||||
pub(crate) fn default_fallback<H, T>(self, handler: H) -> Self
|
||||
where
|
||||
@@ -839,7 +887,7 @@ where
|
||||
panic!(
|
||||
"Overlapping method route. Cannot add two method routes that both handle \
|
||||
`{method_name}`",
|
||||
)
|
||||
);
|
||||
}
|
||||
*out = endpoint.clone();
|
||||
for method in methods {
|
||||
@@ -1614,6 +1662,25 @@ mod tests {
|
||||
assert_eq!(text, "state");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn method_filter() {
|
||||
let router: MethodRouter = get(|| async {});
|
||||
assert_eq!(router.method_filter(), Some(MethodFilter::GET));
|
||||
|
||||
let router: MethodRouter = get(|| async {}).head(|| async {}).post(|| async {});
|
||||
assert_eq!(
|
||||
router.method_filter(),
|
||||
Some(
|
||||
MethodFilter::GET
|
||||
.or(MethodFilter::HEAD)
|
||||
.or(MethodFilter::POST)
|
||||
)
|
||||
);
|
||||
|
||||
let router: MethodRouter = any(|| async {});
|
||||
assert_eq!(router.method_filter(), None);
|
||||
}
|
||||
|
||||
async fn call<S>(method: Method, svc: &mut S) -> (StatusCode, HeaderMap, String)
|
||||
where
|
||||
S: Service<Request, Error = Infallible>,
|
||||
|
||||
@@ -740,6 +740,10 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_default(&self) -> bool {
|
||||
matches!(self, Self::Default(..))
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, E> Clone for Fallback<S, E> {
|
||||
|
||||
Reference in New Issue
Block a user