mirror of
https://github.com/tokio-rs/axum.git
synced 2026-09-07 00:00:12 +02:00
reproduce issue 3004
This commit is contained in:
@@ -43,7 +43,10 @@ typed-routing = ["dep:axum-macros", "dep:percent-encoding", "dep:serde_html_form
|
|||||||
axum = { path = "../axum", version = "0.8.0-alpha.1", default-features = false, features = ["original-uri"] }
|
axum = { path = "../axum", version = "0.8.0-alpha.1", default-features = false, features = ["original-uri"] }
|
||||||
axum-core = { path = "../axum-core", version = "0.5.0-alpha.1" }
|
axum-core = { path = "../axum-core", version = "0.5.0-alpha.1" }
|
||||||
bytes = "1.1.0"
|
bytes = "1.1.0"
|
||||||
futures-util = { version = "0.3", default-features = false, features = ["alloc"] }
|
futures = "*"
|
||||||
|
futures-util = { version = "0.3", default-features = false, features = [
|
||||||
|
"alloc",
|
||||||
|
] }
|
||||||
http = "1.0.0"
|
http = "1.0.0"
|
||||||
http-body = "1.0.0"
|
http-body = "1.0.0"
|
||||||
http-body-util = "0.1.0"
|
http-body-util = "0.1.0"
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ pub mod handler;
|
|||||||
pub mod middleware;
|
pub mod middleware;
|
||||||
pub mod response;
|
pub mod response;
|
||||||
pub mod routing;
|
pub mod routing;
|
||||||
|
mod test_method_routing;
|
||||||
|
|
||||||
#[cfg(feature = "json-lines")]
|
#[cfg(feature = "json-lines")]
|
||||||
pub mod json_lines;
|
pub mod json_lines;
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
convert::Infallible,
|
||||||
|
marker::PhantomData,
|
||||||
|
task::{Context, Poll},
|
||||||
|
};
|
||||||
|
|
||||||
|
use axum::{
|
||||||
|
body::Body,
|
||||||
|
extract::Request,
|
||||||
|
http::StatusCode,
|
||||||
|
response::{IntoResponse, Response},
|
||||||
|
routing::MethodRouter,
|
||||||
|
};
|
||||||
|
use futures::{future::BoxFuture, FutureExt};
|
||||||
|
use tower::Service;
|
||||||
|
|
||||||
|
trait CommandFromBody {
|
||||||
|
fn command_from_body(body: &[u8]) -> Option<&str>;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ExampleService<C> {
|
||||||
|
routes: HashMap<String, MethodRouter>,
|
||||||
|
_phantom_c: PhantomData<fn() -> C>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C> Service<Request> for ExampleService<C>
|
||||||
|
where
|
||||||
|
C: CommandFromBody,
|
||||||
|
{
|
||||||
|
type Error = Infallible;
|
||||||
|
type Response = Response;
|
||||||
|
type Future = BoxFuture<'static, Result<Response, Infallible>>;
|
||||||
|
|
||||||
|
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
|
Poll::Ready(Ok(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&mut self, req: Request) -> Self::Future {
|
||||||
|
async move {
|
||||||
|
let (parts, body) = req.into_parts();
|
||||||
|
|
||||||
|
let Ok(bytes) = axum::body::to_bytes(body, usize::MAX).await else {
|
||||||
|
return Ok(StatusCode::INTERNAL_SERVER_ERROR.into_response());
|
||||||
|
};
|
||||||
|
|
||||||
|
match C::command_from_body(&bytes).and_then(|cmd| self.routes.get(cmd)) {
|
||||||
|
Some(router) => {
|
||||||
|
let req = Request::from_parts(parts, Body::from(bytes));
|
||||||
|
|
||||||
|
router.call_with_state(req, ()).await
|
||||||
|
}
|
||||||
|
|
||||||
|
None => Ok(StatusCode::NOT_FOUND.into_response()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.boxed()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1110,7 +1110,7 @@ where
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn call_with_state(&self, req: Request, state: S) -> RouteFuture<E> {
|
pub fn call_with_state(&self, req: Request, state: S) -> RouteFuture<E> {
|
||||||
macro_rules! call {
|
macro_rules! call {
|
||||||
(
|
(
|
||||||
$req:expr,
|
$req:expr,
|
||||||
|
|||||||
Reference in New Issue
Block a user