mirror of
https://github.com/tokio-rs/axum.git
synced 2025-09-30 22:41:03 +00:00
wip
This commit is contained in:
parent
944f1cbab2
commit
459181f569
@ -1,6 +1,14 @@
|
|||||||
use std::{convert::Infallible, fmt};
|
use std::{convert::Infallible, fmt};
|
||||||
|
|
||||||
use crate::{body::HttpBody, handler::Handler, routing::Route, Router};
|
use http::Request;
|
||||||
|
use tower::Service;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
body::HttpBody,
|
||||||
|
handler::Handler,
|
||||||
|
routing::{future::RouteFuture, Route},
|
||||||
|
Router,
|
||||||
|
};
|
||||||
|
|
||||||
pub(crate) struct BoxedIntoRoute<S, B, E>(Box<dyn ErasedIntoRoute<S, B, E>>);
|
pub(crate) struct BoxedIntoRoute<S, B, E>(Box<dyn ErasedIntoRoute<S, B, E>>);
|
||||||
|
|
||||||
@ -30,6 +38,14 @@ where
|
|||||||
into_route: |router, state| Route::new(router.with_state(state)),
|
into_route: |router, state| Route::new(router.with_state(state)),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn call_with_state(
|
||||||
|
self,
|
||||||
|
request: Request<B>,
|
||||||
|
state: S,
|
||||||
|
) -> RouteFuture<B, Infallible> {
|
||||||
|
self.0.call_with_state(request, state)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, B, E> BoxedIntoRoute<S, B, E> {
|
impl<S, B, E> BoxedIntoRoute<S, B, E> {
|
||||||
@ -39,7 +55,7 @@ impl<S, B, E> BoxedIntoRoute<S, B, E> {
|
|||||||
B: 'static,
|
B: 'static,
|
||||||
E: 'static,
|
E: 'static,
|
||||||
F: FnOnce(Route<B, E>) -> Route<B2, E2> + Clone + Send + 'static,
|
F: FnOnce(Route<B, E>) -> Route<B2, E2> + Clone + Send + 'static,
|
||||||
B2: 'static,
|
B2: HttpBody + 'static,
|
||||||
E2: 'static,
|
E2: 'static,
|
||||||
{
|
{
|
||||||
BoxedIntoRoute(Box::new(Map {
|
BoxedIntoRoute(Box::new(Map {
|
||||||
@ -69,6 +85,8 @@ pub(crate) trait ErasedIntoRoute<S, B, E>: Send {
|
|||||||
fn clone_box(&self) -> Box<dyn ErasedIntoRoute<S, B, E>>;
|
fn clone_box(&self) -> Box<dyn ErasedIntoRoute<S, B, E>>;
|
||||||
|
|
||||||
fn into_route(self: Box<Self>, state: S) -> Route<B, E>;
|
fn into_route(self: Box<Self>, state: S) -> Route<B, E>;
|
||||||
|
|
||||||
|
fn call_with_state(self: Box<Self>, request: Request<B>, state: S) -> RouteFuture<B, E>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct MakeErasedHandler<H, S, B> {
|
pub(crate) struct MakeErasedHandler<H, S, B> {
|
||||||
@ -89,6 +107,14 @@ where
|
|||||||
fn into_route(self: Box<Self>, state: S) -> Route<B> {
|
fn into_route(self: Box<Self>, state: S) -> Route<B> {
|
||||||
(self.into_route)(self.handler, state)
|
(self.into_route)(self.handler, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn call_with_state(
|
||||||
|
self: Box<Self>,
|
||||||
|
request: Request<B>,
|
||||||
|
state: S,
|
||||||
|
) -> RouteFuture<B, Infallible> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H, S, B> Clone for MakeErasedHandler<H, S, B>
|
impl<H, S, B> Clone for MakeErasedHandler<H, S, B>
|
||||||
@ -110,8 +136,8 @@ pub(crate) struct MakeErasedRouter<S, B> {
|
|||||||
|
|
||||||
impl<S, B> ErasedIntoRoute<S, B, Infallible> for MakeErasedRouter<S, B>
|
impl<S, B> ErasedIntoRoute<S, B, Infallible> for MakeErasedRouter<S, B>
|
||||||
where
|
where
|
||||||
S: Clone + Send + 'static,
|
S: Clone + Send + Sync + 'static,
|
||||||
B: 'static,
|
B: HttpBody + Send + 'static,
|
||||||
{
|
{
|
||||||
fn clone_box(&self) -> Box<dyn ErasedIntoRoute<S, B, Infallible>> {
|
fn clone_box(&self) -> Box<dyn ErasedIntoRoute<S, B, Infallible>> {
|
||||||
Box::new(self.clone())
|
Box::new(self.clone())
|
||||||
@ -120,6 +146,14 @@ where
|
|||||||
fn into_route(self: Box<Self>, state: S) -> Route<B> {
|
fn into_route(self: Box<Self>, state: S) -> Route<B> {
|
||||||
(self.into_route)(self.router, state)
|
(self.into_route)(self.router, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn call_with_state(
|
||||||
|
mut self: Box<Self>,
|
||||||
|
request: Request<B>,
|
||||||
|
state: S,
|
||||||
|
) -> RouteFuture<B, Infallible> {
|
||||||
|
self.router.call_with_state(request, state)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, B> Clone for MakeErasedRouter<S, B>
|
impl<S, B> Clone for MakeErasedRouter<S, B>
|
||||||
@ -144,7 +178,7 @@ where
|
|||||||
S: 'static,
|
S: 'static,
|
||||||
B: 'static,
|
B: 'static,
|
||||||
E: 'static,
|
E: 'static,
|
||||||
B2: 'static,
|
B2: HttpBody + 'static,
|
||||||
E2: 'static,
|
E2: 'static,
|
||||||
{
|
{
|
||||||
fn clone_box(&self) -> Box<dyn ErasedIntoRoute<S, B2, E2>> {
|
fn clone_box(&self) -> Box<dyn ErasedIntoRoute<S, B2, E2>> {
|
||||||
@ -157,6 +191,11 @@ where
|
|||||||
fn into_route(self: Box<Self>, state: S) -> Route<B2, E2> {
|
fn into_route(self: Box<Self>, state: S) -> Route<B2, E2> {
|
||||||
(self.layer)(self.inner.into_route(state))
|
(self.layer)(self.inner.into_route(state))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn call_with_state(self: Box<Self>, request: Request<B2>, state: S) -> RouteFuture<B2, E2> {
|
||||||
|
let route = (self.layer)(self.inner.into_route(state));
|
||||||
|
route.call(request)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait LayerFn<B, E, B2, E2>: FnOnce(Route<B, E>) -> Route<B2, E2> + Send {
|
pub(crate) trait LayerFn<B, E, B2, E2>: FnOnce(Route<B, E>) -> Route<B2, E2> + Send {
|
||||||
|
@ -407,6 +407,102 @@ where
|
|||||||
pub fn with_state(self, state: S) -> RouterService<B> {
|
pub fn with_state(self, state: S) -> RouterService<B> {
|
||||||
RouterService::new(self, state)
|
RouterService::new(self, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn call_with_state(
|
||||||
|
&mut self,
|
||||||
|
mut req: Request<B>,
|
||||||
|
state: S,
|
||||||
|
) -> RouteFuture<B, Infallible> {
|
||||||
|
#[cfg(feature = "original-uri")]
|
||||||
|
{
|
||||||
|
use crate::extract::OriginalUri;
|
||||||
|
|
||||||
|
if req.extensions().get::<OriginalUri>().is_none() {
|
||||||
|
let original_uri = OriginalUri(req.uri().clone());
|
||||||
|
req.extensions_mut().insert(original_uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let path = req.uri().path().to_owned();
|
||||||
|
|
||||||
|
match self.node.at(&path) {
|
||||||
|
Ok(match_) => {
|
||||||
|
match &self.fallback {
|
||||||
|
Fallback::Default(_) => {}
|
||||||
|
Fallback::Service(fallback) => {
|
||||||
|
req.extensions_mut()
|
||||||
|
.insert(SuperFallback(SyncWrapper::new(fallback.clone())));
|
||||||
|
}
|
||||||
|
Fallback::BoxedHandler(fallback) => {
|
||||||
|
req.extensions_mut().insert(SuperFallback(SyncWrapper::new(
|
||||||
|
fallback.clone().into_route(state.clone()),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.call_route(match_, req, state)
|
||||||
|
}
|
||||||
|
Err(
|
||||||
|
MatchError::NotFound
|
||||||
|
| MatchError::ExtraTrailingSlash
|
||||||
|
| MatchError::MissingTrailingSlash,
|
||||||
|
) => {
|
||||||
|
match &mut self.fallback {
|
||||||
|
Fallback::Default(fallback) => {
|
||||||
|
if let Some(super_fallback) =
|
||||||
|
req.extensions_mut().remove::<SuperFallback<B>>()
|
||||||
|
{
|
||||||
|
let mut super_fallback = super_fallback.0.into_inner();
|
||||||
|
super_fallback.call(req)
|
||||||
|
} else {
|
||||||
|
fallback.call(req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fallback::Service(fallback) => fallback.call(req),
|
||||||
|
Fallback::BoxedHandler(handler) => {
|
||||||
|
todo!()
|
||||||
|
// handler.clone().into_route(state).call(req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(david): fix duplication
|
||||||
|
#[inline]
|
||||||
|
fn call_route(
|
||||||
|
&self,
|
||||||
|
match_: matchit::Match<&RouteId>,
|
||||||
|
mut req: Request<B>,
|
||||||
|
state: S,
|
||||||
|
) -> RouteFuture<B, Infallible> {
|
||||||
|
let id = *match_.value;
|
||||||
|
|
||||||
|
#[cfg(feature = "matched-path")]
|
||||||
|
crate::extract::matched_path::set_matched_path_for_request(
|
||||||
|
id,
|
||||||
|
&self.node.route_id_to_path,
|
||||||
|
req.extensions_mut(),
|
||||||
|
);
|
||||||
|
|
||||||
|
url_params::insert_url_params(req.extensions_mut(), match_.params);
|
||||||
|
|
||||||
|
let endpont = self
|
||||||
|
.routes
|
||||||
|
.get(&id)
|
||||||
|
.expect("no route for id. This is a bug in axum. Please file an issue")
|
||||||
|
.clone();
|
||||||
|
|
||||||
|
match endpont {
|
||||||
|
Endpoint::MethodRouter(method_router) => {
|
||||||
|
// method_router.call(req)
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
Endpoint::Route(mut route) => route.call(req),
|
||||||
|
// TODO(david): optimize?
|
||||||
|
Endpoint::NestedRouter(router) => router.call_with_state(req, state),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> Router<(), B>
|
impl<B> Router<(), B>
|
||||||
@ -460,38 +556,6 @@ where
|
|||||||
) -> IntoMakeServiceWithConnectInfo<RouterService<B>, C> {
|
) -> IntoMakeServiceWithConnectInfo<RouterService<B>, C> {
|
||||||
IntoMakeServiceWithConnectInfo::new(self.into_service())
|
IntoMakeServiceWithConnectInfo::new(self.into_service())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(david): fix duplication
|
|
||||||
#[inline]
|
|
||||||
fn call_route(
|
|
||||||
&self,
|
|
||||||
match_: matchit::Match<&RouteId>,
|
|
||||||
mut req: Request<B>,
|
|
||||||
) -> RouteFuture<B, Infallible> {
|
|
||||||
let id = *match_.value;
|
|
||||||
|
|
||||||
#[cfg(feature = "matched-path")]
|
|
||||||
crate::extract::matched_path::set_matched_path_for_request(
|
|
||||||
id,
|
|
||||||
&self.node.route_id_to_path,
|
|
||||||
req.extensions_mut(),
|
|
||||||
);
|
|
||||||
|
|
||||||
url_params::insert_url_params(req.extensions_mut(), match_.params);
|
|
||||||
|
|
||||||
let endpont = self
|
|
||||||
.routes
|
|
||||||
.get(&id)
|
|
||||||
.expect("no route for id. This is a bug in axum. Please file an issue")
|
|
||||||
.clone();
|
|
||||||
|
|
||||||
match endpont {
|
|
||||||
Endpoint::MethodRouter(mut method_router) => method_router.call(req),
|
|
||||||
Endpoint::Route(mut route) => route.call(req),
|
|
||||||
// TODO(david): optimize?
|
|
||||||
Endpoint::NestedRouter(router) => router.into_route(()).call(req),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(david): fix duplication
|
// TODO(david): fix duplication
|
||||||
@ -509,58 +573,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn call(&mut self, mut req: Request<B>) -> Self::Future {
|
fn call(&mut self, req: Request<B>) -> Self::Future {
|
||||||
#[cfg(feature = "original-uri")]
|
self.call_with_state(req, ())
|
||||||
{
|
|
||||||
use crate::extract::OriginalUri;
|
|
||||||
|
|
||||||
if req.extensions().get::<OriginalUri>().is_none() {
|
|
||||||
let original_uri = OriginalUri(req.uri().clone());
|
|
||||||
req.extensions_mut().insert(original_uri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let path = req.uri().path().to_owned();
|
|
||||||
|
|
||||||
match self.node.at(&path) {
|
|
||||||
Ok(match_) => {
|
|
||||||
match &self.fallback {
|
|
||||||
Fallback::Default(_) => {}
|
|
||||||
Fallback::Service(fallback) => {
|
|
||||||
req.extensions_mut()
|
|
||||||
.insert(SuperFallback(SyncWrapper::new(fallback.clone())));
|
|
||||||
}
|
|
||||||
Fallback::BoxedHandler(fallback) => {
|
|
||||||
req.extensions_mut().insert(SuperFallback(SyncWrapper::new(
|
|
||||||
fallback.clone().into_route(()),
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.call_route(match_, req)
|
|
||||||
}
|
|
||||||
Err(
|
|
||||||
MatchError::NotFound
|
|
||||||
| MatchError::ExtraTrailingSlash
|
|
||||||
| MatchError::MissingTrailingSlash,
|
|
||||||
) => {
|
|
||||||
//
|
|
||||||
match &mut self.fallback {
|
|
||||||
Fallback::Default(fallback) => {
|
|
||||||
if let Some(super_fallback) =
|
|
||||||
req.extensions_mut().remove::<SuperFallback<B>>()
|
|
||||||
{
|
|
||||||
let mut super_fallback = super_fallback.0.into_inner();
|
|
||||||
super_fallback.call(req)
|
|
||||||
} else {
|
|
||||||
fallback.call(req)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Fallback::Service(fallback) => fallback.call(req),
|
|
||||||
Fallback::BoxedHandler(handler) => handler.clone().into_route(()).call(req),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -639,7 +653,7 @@ where
|
|||||||
B: 'static,
|
B: 'static,
|
||||||
E: 'static,
|
E: 'static,
|
||||||
F: FnOnce(Route<B, E>) -> Route<B2, E2> + Clone + Send + 'static,
|
F: FnOnce(Route<B, E>) -> Route<B2, E2> + Clone + Send + 'static,
|
||||||
B2: 'static,
|
B2: HttpBody + 'static,
|
||||||
E2: 'static,
|
E2: 'static,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user