Remove `B` type param: Follow ups (#1789)

Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
Co-authored-by: Michael Scofield <mscofield0@tutanota.com>
This commit is contained in:
David Pedersen 2023-03-20 21:02:40 +01:00
parent 72c1b7a80c
commit 6703f8634c
70 changed files with 429 additions and 531 deletions

View File

@ -1,6 +1,5 @@
//! HTTP body utilities.
use crate::response::{IntoResponse, Response};
use crate::{BoxError, Error};
use bytes::Bytes;
use bytes::{Buf, BufMut};
@ -13,14 +12,9 @@ use std::pin::Pin;
use std::task::{Context, Poll};
use sync_wrapper::SyncWrapper;
/// A boxed [`Body`] trait object.
///
/// This is used in axum as the response body type for applications. It's
/// necessary to unify multiple response bodies types into one.
pub type BoxBody = http_body::combinators::UnsyncBoxBody<Bytes, Error>;
type BoxBody = http_body::combinators::UnsyncBoxBody<Bytes, Error>;
/// Convert a [`http_body::Body`] into a [`BoxBody`].
pub fn boxed<B>(body: B) -> BoxBody
fn boxed<B>(body: B) -> BoxBody
where
B: http_body::Body<Data = Bytes> + Send + 'static,
B::Error: Into<BoxError>,
@ -230,12 +224,6 @@ where
}
}
impl IntoResponse for Body {
fn into_response(self) -> Response {
Response::new(self.0)
}
}
#[test]
fn test_try_downcast() {
assert_eq!(try_downcast::<i32, _>(5_u32), Err(5_u32));

View File

@ -1,7 +1,6 @@
use crate::body::Body;
use crate::extract::{DefaultBodyLimitKind, FromRequest, FromRequestParts};
use crate::extract::{DefaultBodyLimitKind, FromRequest, FromRequestParts, Request};
use futures_util::future::BoxFuture;
use http::Request;
use http_body::Limited;
mod sealed {
@ -23,9 +22,9 @@ pub trait RequestExt: sealed::Sealed + Sized {
/// ```
/// use axum::{
/// async_trait,
/// extract::FromRequest,
/// extract::{Request, FromRequest},
/// body::Body,
/// http::{header::CONTENT_TYPE, Request, StatusCode},
/// http::{header::CONTENT_TYPE, StatusCode},
/// response::{IntoResponse, Response},
/// Form, Json, RequestExt,
/// };
@ -42,7 +41,7 @@ pub trait RequestExt: sealed::Sealed + Sized {
/// {
/// type Rejection = Response;
///
/// async fn from_request(req: Request<Body>, _state: &S) -> Result<Self, Self::Rejection> {
/// async fn from_request(req: Request, _state: &S) -> Result<Self, Self::Rejection> {
/// let content_type = req
/// .headers()
/// .get(CONTENT_TYPE)
@ -87,8 +86,7 @@ pub trait RequestExt: sealed::Sealed + Sized {
/// use axum::{
/// async_trait,
/// body::Body,
/// extract::{FromRef, FromRequest},
/// http::Request,
/// extract::{Request, FromRef, FromRequest},
/// RequestExt,
/// };
///
@ -104,7 +102,7 @@ pub trait RequestExt: sealed::Sealed + Sized {
/// {
/// type Rejection = std::convert::Infallible;
///
/// async fn from_request(req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
/// async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
/// let requires_state = req.extract_with_state::<RequiresState, _, _>(state).await?;
///
/// Ok(Self { requires_state })
@ -122,7 +120,7 @@ pub trait RequestExt: sealed::Sealed + Sized {
/// {
/// // ...
/// # type Rejection = std::convert::Infallible;
/// # async fn from_request(req: Request<Body>, _state: &S) -> Result<Self, Self::Rejection> {
/// # async fn from_request(req: Request, _state: &S) -> Result<Self, Self::Rejection> {
/// # todo!()
/// # }
/// }
@ -141,9 +139,8 @@ pub trait RequestExt: sealed::Sealed + Sized {
/// ```
/// use axum::{
/// async_trait,
/// extract::FromRequest,
/// extract::{Request, FromRequest},
/// headers::{authorization::Bearer, Authorization},
/// http::Request,
/// response::{IntoResponse, Response},
/// body::Body,
/// Json, RequestExt, TypedHeader,
@ -163,7 +160,7 @@ pub trait RequestExt: sealed::Sealed + Sized {
/// {
/// type Rejection = Response;
///
/// async fn from_request(mut req: Request<Body>, _state: &S) -> Result<Self, Self::Rejection> {
/// async fn from_request(mut req: Request, _state: &S) -> Result<Self, Self::Rejection> {
/// let TypedHeader(auth_header) = req
/// .extract_parts::<TypedHeader<Authorization<Bearer>>>()
/// .await
@ -194,8 +191,8 @@ pub trait RequestExt: sealed::Sealed + Sized {
/// ```
/// use axum::{
/// async_trait,
/// extract::{FromRef, FromRequest, FromRequestParts},
/// http::{request::Parts, Request},
/// extract::{Request, FromRef, FromRequest, FromRequestParts},
/// http::request::Parts,
/// response::{IntoResponse, Response},
/// body::Body,
/// Json, RequestExt,
@ -216,7 +213,7 @@ pub trait RequestExt: sealed::Sealed + Sized {
/// {
/// type Rejection = Response;
///
/// async fn from_request(mut req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
/// async fn from_request(mut req: Request, state: &S) -> Result<Self, Self::Rejection> {
/// let requires_state = req
/// .extract_parts_with_state::<RequiresState, _>(state)
/// .await
@ -260,7 +257,7 @@ pub trait RequestExt: sealed::Sealed + Sized {
/// Apply the [default body limit](crate::extract::DefaultBodyLimit).
///
/// If it is disabled, return the request as-is in `Err`.
fn with_limited_body(self) -> Result<Request<Limited<Body>>, Request<Body>>;
fn with_limited_body(self) -> Result<Request<Limited<Body>>, Request>;
/// Consumes the request, returning the body wrapped in [`Limited`] if a
/// [default limit](crate::extract::DefaultBodyLimit) is in place, or not wrapped if the
@ -268,7 +265,7 @@ pub trait RequestExt: sealed::Sealed + Sized {
fn into_limited_body(self) -> Result<Limited<Body>, Body>;
}
impl RequestExt for Request<Body> {
impl RequestExt for Request {
fn extract<E, M>(self) -> BoxFuture<'static, Result<E, E::Rejection>>
where
E: FromRequest<(), M> + 'static,
@ -321,7 +318,7 @@ impl RequestExt for Request<Body> {
})
}
fn with_limited_body(self) -> Result<Request<Limited<Body>>, Request<Body>> {
fn with_limited_body(self) -> Result<Request<Limited<Body>>, Request> {
// update docs in `axum-core/src/extract/default_body_limit.rs` and
// `axum/src/docs/extract.md` if this changes
const DEFAULT_LIMIT: usize = 2_097_152; // 2 mb
@ -426,7 +423,7 @@ mod tests {
{
type Rejection = <String as FromRequest<()>>::Rejection;
async fn from_request(mut req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(mut req: Request, state: &S) -> Result<Self, Self::Rejection> {
let RequiresState(from_state) = req.extract_parts_with_state(state).await.unwrap();
let method = req.extract_parts().await.unwrap();
let body = req.extract().await?;

View File

@ -30,22 +30,21 @@ use tower_layer::Layer;
/// Router,
/// routing::post,
/// body::Body,
/// extract::{DefaultBodyLimit, RawBody},
/// http::Request,
/// extract::{Request, DefaultBodyLimit},
/// };
///
/// let app = Router::new()
/// .route(
/// "/",
/// // even with `DefaultBodyLimit` the request body is still just `Body`
/// post(|request: Request<Body>| async {}),
/// post(|request: Request| async {}),
/// )
/// .layer(DefaultBodyLimit::max(1024));
/// # let _: Router = app;
/// ```
///
/// ```
/// use axum::{Router, routing::post, body::Body, extract::RawBody, http::Request};
/// use axum::{Router, routing::post, body::Body, extract::Request};
/// use tower_http::limit::RequestBodyLimitLayer;
/// use http_body::Limited;
///
@ -54,7 +53,7 @@ use tower_layer::Layer;
/// "/",
/// // `RequestBodyLimitLayer` changes the request body type to `Limited<Body>`
/// // extracting a different body type wont work
/// post(|request: Request<Body>| async {}),
/// post(|request: Request| async {}),
/// )
/// .layer(RequestBodyLimitLayer::new(1024));
/// # let _: Router = app;

View File

@ -6,7 +6,7 @@
use crate::{body::Body, response::IntoResponse};
use async_trait::async_trait;
use http::{request::Parts, Request};
use http::request::Parts;
use std::convert::Infallible;
pub mod rejection;
@ -19,6 +19,10 @@ mod tuple;
pub(crate) use self::default_body_limit::DefaultBodyLimitKind;
pub use self::{default_body_limit::DefaultBodyLimit, from_ref::FromRef};
/// Type alias for [`http::Request`] whose body type defaults to [`Body`], the most common body
/// type used with axum.
pub type Request<T = Body> = http::Request<T>;
mod private {
#[derive(Debug, Clone, Copy)]
pub enum ViaParts {}
@ -78,7 +82,7 @@ pub trait FromRequest<S, M = private::ViaRequest>: Sized {
type Rejection: IntoResponse;
/// Perform the extraction.
async fn from_request(req: Request<Body>, state: &S) -> Result<Self, Self::Rejection>;
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection>;
}
#[async_trait]
@ -89,7 +93,7 @@ where
{
type Rejection = <Self as FromRequestParts<S>>::Rejection;
async fn from_request(req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
let (mut parts, _) = req.into_parts();
Self::from_request_parts(&mut parts, state).await
}
@ -119,7 +123,7 @@ where
{
type Rejection = Infallible;
async fn from_request(req: Request<Body>, state: &S) -> Result<Option<T>, Self::Rejection> {
async fn from_request(req: Request, state: &S) -> Result<Option<T>, Self::Rejection> {
Ok(T::from_request(req, state).await.ok())
}
}
@ -145,7 +149,7 @@ where
{
type Rejection = Infallible;
async fn from_request(req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
Ok(T::from_request(req, state).await)
}
}

View File

@ -1,18 +1,18 @@
use super::{rejection::*, FromRequest, FromRequestParts};
use super::{rejection::*, FromRequest, FromRequestParts, Request};
use crate::{body::Body, RequestExt};
use async_trait::async_trait;
use bytes::Bytes;
use http::{request::Parts, HeaderMap, Method, Request, Uri, Version};
use http::{request::Parts, HeaderMap, Method, Uri, Version};
use std::convert::Infallible;
#[async_trait]
impl<S> FromRequest<S> for Request<Body>
impl<S> FromRequest<S> for Request
where
S: Send + Sync,
{
type Rejection = Infallible;
async fn from_request(req: Request<Body>, _: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, _: &S) -> Result<Self, Self::Rejection> {
Ok(req)
}
}
@ -77,7 +77,7 @@ where
{
type Rejection = BytesRejection;
async fn from_request(req: Request<Body>, _: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, _: &S) -> Result<Self, Self::Rejection> {
let bytes = match req.into_limited_body() {
Ok(limited_body) => crate::body::to_bytes(limited_body)
.await
@ -98,7 +98,7 @@ where
{
type Rejection = StringRejection;
async fn from_request(req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
let bytes = Bytes::from_request(req, state)
.await
.map_err(|err| match err {
@ -122,7 +122,19 @@ where
{
type Rejection = Infallible;
async fn from_request(req: Request<Body>, _: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, _: &S) -> Result<Self, Self::Rejection> {
Ok(req.into_parts().0)
}
}
#[async_trait]
impl<S> FromRequest<S> for Body
where
S: Send + Sync,
{
type Rejection = Infallible;
async fn from_request(req: Request, _: &S) -> Result<Self, Self::Rejection> {
Ok(req.into_body())
}
}

View File

@ -1,8 +1,7 @@
use super::{FromRequest, FromRequestParts};
use crate::body::Body;
use super::{FromRequest, FromRequestParts, Request};
use crate::response::{IntoResponse, Response};
use async_trait::async_trait;
use http::request::{Parts, Request};
use http::request::Parts;
use std::convert::Infallible;
#[async_trait]
@ -57,7 +56,7 @@ macro_rules! impl_from_request {
{
type Rejection = Response;
async fn from_request(req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
let (mut parts, body) = req.into_parts();
$(

View File

@ -1,5 +1,5 @@
use super::{IntoResponseParts, Response, ResponseParts};
use crate::{body, BoxError};
use crate::{body::Body, BoxError};
use bytes::{buf::Chain, Buf, Bytes, BytesMut};
use http::{
header::{self, HeaderMap, HeaderName, HeaderValue},
@ -74,9 +74,9 @@ use std::{
/// body,
/// routing::get,
/// response::{IntoResponse, Response},
/// body::Body,
/// Router,
/// };
/// use http_body::Body;
/// use http::HeaderMap;
/// use bytes::Bytes;
/// use std::{
@ -89,7 +89,7 @@ use std::{
///
/// // First implement `Body` for `MyBody`. This could for example use
/// // some custom streaming protocol.
/// impl Body for MyBody {
/// impl http_body::Body for MyBody {
/// type Data = Bytes;
/// type Error = Infallible;
///
@ -113,7 +113,7 @@ use std::{
/// // Now we can implement `IntoResponse` directly for `MyBody`
/// impl IntoResponse for MyBody {
/// fn into_response(self) -> Response {
/// Response::new(body::boxed(self))
/// Response::new(Body::new(self))
/// }
/// }
///
@ -165,25 +165,31 @@ where
B::Error: Into<BoxError>,
{
fn into_response(self) -> Response {
self.map(body::boxed)
self.map(Body::new)
}
}
impl IntoResponse for http::response::Parts {
fn into_response(self) -> Response {
Response::from_parts(self, body::boxed(Empty::new()))
Response::from_parts(self, Body::empty())
}
}
impl IntoResponse for Full<Bytes> {
fn into_response(self) -> Response {
Response::new(body::boxed(self))
Response::new(Body::new(self))
}
}
impl IntoResponse for Empty<Bytes> {
fn into_response(self) -> Response {
Response::new(body::boxed(self))
Response::new(Body::new(self))
}
}
impl IntoResponse for Body {
fn into_response(self) -> Response {
Response::new(self)
}
}
@ -192,7 +198,7 @@ where
E: Into<BoxError> + 'static,
{
fn into_response(self) -> Response {
Response::new(body::boxed(self))
Response::new(Body::new(self))
}
}
@ -201,7 +207,7 @@ where
E: Into<BoxError> + 'static,
{
fn into_response(self) -> Response {
Response::new(body::boxed(self))
Response::new(Body::new(self))
}
}
@ -212,7 +218,7 @@ where
B::Error: Into<BoxError>,
{
fn into_response(self) -> Response {
Response::new(body::boxed(self))
Response::new(Body::new(self))
}
}
@ -223,7 +229,7 @@ where
E: Into<BoxError>,
{
fn into_response(self) -> Response {
Response::new(body::boxed(self))
Response::new(Body::new(self))
}
}
@ -274,7 +280,7 @@ where
{
fn into_response(self) -> Response {
let (first, second) = self.into_inner();
let mut res = Response::new(body::boxed(BytesChainBody {
let mut res = Response::new(Body::new(BytesChainBody {
first: Some(first),
second: Some(second),
}));

View File

@ -4,7 +4,7 @@
//!
//! [`axum::response`]: https://docs.rs/axum/latest/axum/response/index.html
use crate::body::BoxBody;
use crate::body::Body;
mod append_headers;
mod into_response;
@ -16,9 +16,9 @@ pub use self::{
into_response_parts::{IntoResponseParts, ResponseParts, TryIntoHeaderError},
};
/// Type alias for [`http::Response`] whose body type defaults to [`BoxBody`], the most common body
/// Type alias for [`http::Response`] whose body type defaults to [`Body`], the most common body
/// type used with axum.
pub type Response<T = BoxBody> = http::Response<T>;
pub type Response<T = Body> = http::Response<T>;
/// An [`IntoResponse`]-based result type that uses [`ErrorResponse`] as the error type.
///

View File

@ -21,7 +21,6 @@ use http::request::Parts;
/// use axum::{
/// async_trait,
/// extract::FromRequestParts,
/// body::BoxBody,
/// response::{IntoResponse, Response},
/// http::{StatusCode, request::Parts},
/// };

View File

@ -1,11 +1,10 @@
use axum::{
async_trait,
body::Body,
extract::{rejection::RawFormRejection, FromRequest, RawForm},
extract::{rejection::RawFormRejection, FromRequest, RawForm, Request},
response::{IntoResponse, Response},
Error, RequestExt,
};
use http::{Request, StatusCode};
use http::StatusCode;
use serde::de::DeserializeOwned;
use std::fmt;
@ -53,7 +52,7 @@ where
{
type Rejection = FormRejection;
async fn from_request(req: Request<Body>, _state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, _state: &S) -> Result<Self, Self::Rejection> {
let RawForm(bytes) = req
.extract()
.await

View File

@ -1,9 +1,7 @@
use axum::async_trait;
use axum::body::Body;
use axum::extract::{FromRequest, FromRequestParts};
use axum::extract::{FromRequest, FromRequestParts, Request};
use axum::response::IntoResponse;
use http::request::Parts;
use http::Request;
use std::fmt::Debug;
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
@ -118,7 +116,7 @@ where
{
type Rejection = R;
async fn from_request(req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
let extractor = E::from_request(req, state).await?;
Ok(WithRejection(extractor, PhantomData))
}
@ -141,6 +139,7 @@ where
#[cfg(test)]
mod tests {
use axum::body::Body;
use axum::extract::FromRequestParts;
use axum::http::Request;
use axum::response::Response;

View File

@ -1,6 +1,7 @@
//! Additional handler utilities.
use axum::body::Body;
use axum::extract::Request;
use axum::{
extract::FromRequest,
handler::Handler,
@ -174,7 +175,7 @@ where
{
type Future = BoxFuture<'static, Response>;
fn call(self, req: http::Request<Body>, state: S) -> Self::Future {
fn call(self, req: Request, state: S) -> Self::Future {
let req = req.map(Body::new);
Box::pin(async move {
match T::from_request(req, &state).await {

View File

@ -1,10 +1,8 @@
use super::HandlerCallWithExtractors;
use crate::either::Either;
use axum::{
body::Body,
extract::{FromRequest, FromRequestParts},
extract::{FromRequest, FromRequestParts, Request},
handler::Handler,
http::Request,
response::{IntoResponse, Response},
};
use futures_util::future::{BoxFuture, Either as EitherFuture, FutureExt, Map};
@ -67,7 +65,7 @@ where
// this puts `futures_util` in our public API but thats fine in axum-extra
type Future = BoxFuture<'static, Response>;
fn call(self, req: Request<Body>, state: S) -> Self::Future {
fn call(self, req: Request, state: S) -> Self::Future {
Box::pin(async move {
let (mut parts, body) = req.into_parts();

View File

@ -3,13 +3,12 @@
use axum::{
async_trait,
body::Body,
extract::FromRequest,
extract::{FromRequest, Request},
response::{IntoResponse, Response},
BoxError,
};
use bytes::{BufMut, BytesMut};
use futures_util::stream::{BoxStream, Stream, TryStream, TryStreamExt};
use http::Request;
use pin_project_lite::pin_project;
use serde::{de::DeserializeOwned, Serialize};
use std::{
@ -108,7 +107,7 @@ where
{
type Rejection = Infallible;
async fn from_request(req: Request<Body>, _state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, _state: &S) -> Result<Self, Self::Rejection> {
// `Stream::lines` isn't a thing so we have to convert it into an `AsyncRead`
// so we can call `AsyncRead::lines` and then convert it back to a `Stream`
let body = req.into_body();

View File

@ -2,12 +2,11 @@
use axum::{
async_trait,
body::Body,
extract::{rejection::BytesRejection, FromRequest},
extract::{rejection::BytesRejection, FromRequest, Request},
response::{IntoResponse, Response},
};
use bytes::{Bytes, BytesMut};
use http::{Request, StatusCode};
use http::StatusCode;
use prost::Message;
/// A Protocol Buffer message extractor and response.
@ -103,7 +102,7 @@ where
{
type Rejection = ProtobufRejection;
async fn from_request(req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
let mut bytes = Bytes::from_request(req, state).await?;
match T::decode(&mut bytes) {
@ -273,16 +272,16 @@ mod tests {
result: String,
}
let app = Router::new().route(
"/",
post(|input: Protobuf<Input>| async move {
let output = Output {
result: input.foo.to_owned(),
};
#[axum::debug_handler]
async fn handler(input: Protobuf<Input>) -> Protobuf<Output> {
let output = Output {
result: input.foo.to_owned(),
};
Protobuf(output)
}),
);
Protobuf(output)
}
let app = Router::new().route("/", post(handler));
let input = Input {
foo: "bar".to_owned(),

View File

@ -1,8 +1,7 @@
//! Additional types for defining routes.
use axum::{
body::Body,
http::Request,
extract::Request,
response::{IntoResponse, Redirect, Response},
routing::{any, MethodRouter},
Router,
@ -166,7 +165,7 @@ pub trait RouterExt<S>: sealed::Sealed {
/// This works like [`RouterExt::route_with_tsr`] but accepts any [`Service`].
fn route_service_with_tsr<T>(self, path: &str, service: T) -> Self
where
T: Service<Request<Body>, Error = Infallible> + Clone + Send + 'static,
T: Service<Request, Error = Infallible> + Clone + Send + 'static,
T::Response: IntoResponse,
T::Future: Send + 'static,
Self: Sized;
@ -269,7 +268,7 @@ where
#[track_caller]
fn route_service_with_tsr<T>(mut self, path: &str, service: T) -> Self
where
T: Service<Request<Body>, Error = Infallible> + Clone + Send + 'static,
T: Service<Request, Error = Infallible> + Clone + Send + 'static,
T::Response: IntoResponse,
T::Future: Send + 'static,
Self: Sized,

View File

@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
request-consuming extractors ([#1826])
[#1826]: https://github.com/tokio-rs/axum/pull/1826
[#1751]: https://github.com/tokio-rs/axum/pull/1751
# 0.3.5 (03. March, 2023)

View File

@ -43,10 +43,9 @@ pub(crate) fn expand(attr: Attrs, item_fn: ItemFn) -> TokenStream {
err.unwrap_or_else(|| {
let state_ty = state_ty.unwrap_or_else(|| syn::parse_quote!(()));
let check_input_order = check_input_order(&item_fn);
let check_future_send = check_future_send(&item_fn);
if let Some(check_input_order) = check_input_order {
if let Some(check_input_order) = check_input_order(&item_fn) {
quote! {
#check_input_order
#check_future_send

View File

@ -1,7 +1,6 @@
use axum::{
async_trait,
extract::FromRequest,
http::Request,
extract::{Request, FromRequest},
};
use axum_macros::debug_handler;
@ -14,7 +13,7 @@ where
{
type Rejection = ();
async fn from_request(_req: Request<axum::body::Body>, _state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(_req: Request, _state: &S) -> Result<Self, Self::Rejection> {
unimplemented!()
}
}

View File

@ -1,5 +1,5 @@
error: Handlers must only take owned values
--> tests/debug_handler/fail/extract_self_mut.rs:24:22
--> tests/debug_handler/fail/extract_self_mut.rs:23:22
|
24 | async fn handler(&mut self) {}
23 | async fn handler(&mut self) {}
| ^^^^^^^^^

View File

@ -1,7 +1,6 @@
use axum::{
async_trait,
extract::FromRequest,
http::Request,
extract::{Request, FromRequest},
};
use axum_macros::debug_handler;
@ -14,7 +13,7 @@ where
{
type Rejection = ();
async fn from_request(_req: Request<axum::body::Body>, _state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(_req: Request, _state: &S) -> Result<Self, Self::Rejection> {
unimplemented!()
}
}

View File

@ -1,5 +1,5 @@
error: Handlers must only take owned values
--> tests/debug_handler/fail/extract_self_ref.rs:24:22
--> tests/debug_handler/fail/extract_self_ref.rs:23:22
|
24 | async fn handler(&self) {}
23 | async fn handler(&self) {}
| ^^^^^

View File

@ -1,7 +1,7 @@
use axum::{body::Body, extract::Extension, http::Request};
use axum::extract::{Extension, Request};
use axum_macros::debug_handler;
#[debug_handler]
async fn handler(_: Extension<String>, _: Request<Body>) {}
async fn handler(_: Extension<String>, _: Request) {}
fn main() {}

View File

@ -1,7 +1,6 @@
use axum::{
async_trait,
extract::FromRequest,
http::Request,
extract::{Request, FromRequest},
};
use axum_macros::debug_handler;
@ -14,7 +13,7 @@ where
{
type Rejection = ();
async fn from_request(_req: Request<axum::body::Body>, _state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(_req: Request, _state: &S) -> Result<Self, Self::Rejection> {
unimplemented!()
}
}
@ -26,7 +25,7 @@ where
{
type Rejection = ();
async fn from_request(_req: Request<axum::body::Body>, _state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(_req: Request, _state: &S) -> Result<Self, Self::Rejection> {
unimplemented!()
}
}

View File

@ -1,7 +1,6 @@
use axum_macros::debug_handler;
use axum::extract::{FromRef, FromRequest};
use axum::extract::{Request, FromRef, FromRequest};
use axum::async_trait;
use axum::http::Request;
#[debug_handler(state = AppState)]
async fn handler(_: A) {}
@ -19,7 +18,7 @@ where
{
type Rejection = ();
async fn from_request(_req: Request<axum::body::Body>, _state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(_req: Request, _state: &S) -> Result<Self, Self::Rejection> {
unimplemented!()
}
}

View File

@ -1,8 +1,8 @@
use axum_macros::debug_handler;
use axum::{extract::State, http::Request};
use axum::{extract::State, extract::Request};
#[debug_handler(state = AppState)]
async fn handler(_: State<AppState>, _: Request<axum::body::Body>) {}
async fn handler(_: State<AppState>, _: Request) {}
#[derive(Clone)]
struct AppState;

View File

@ -1,7 +1,7 @@
use axum::{
async_trait,
extract::{rejection::ExtensionRejection, FromRequest},
http::{StatusCode, Request},
extract::{Request, rejection::ExtensionRejection, FromRequest},
http::StatusCode,
response::{IntoResponse, Response},
routing::get,
body::Body,
@ -35,7 +35,7 @@ where
// this rejection doesn't implement `Display` and `Error`
type Rejection = (StatusCode, String);
async fn from_request(_req: Request<Body>, _state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(_req: Request, _state: &S) -> Result<Self, Self::Rejection> {
todo!()
}
}

View File

@ -8,18 +8,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
# Unreleased
- **breaking:** The following types/traits are no longer generic over the request body
(i.e. the `B` type param has been removed) ([#1751]):
- `FromRequest`
(i.e. the `B` type param has been removed) ([#1751] and [#1789]):
- `FromRequestParts`
- `Handler`
- `FromRequest`
- `HandlerService`
- `HandlerWithoutStateExt`
- `Layered`
- `Handler`
- `LayeredFuture`
- `Layered`
- `MethodRouter`
- `Next`
- `RequestExt`
- `Route`
- `RouteFuture`
- `Route`
- `Router`
- **breaking:** axum no longer re-exports `hyper::Body` as that type is removed
in hyper 1.0. Instead axum has its own body type at `axum::body::Body` ([#1751])
@ -28,6 +29,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **breaking:** Change `sse::Event::json_data` to use `axum_core::Error` as its error type ([#1762])
- **breaking:** Rename `DefaultOnFailedUpdgrade` to `DefaultOnFailedUpgrade` ([#1664])
- **breaking:** Rename `OnFailedUpdgrade` to `OnFailedUpgrade` ([#1664])
- **breaking:** Removed re-exports of `Empty` and `Full`. Use
`axum::body::Body::empty` and `axum::body::Body::from` respectively ([#1789])
- **breaking:** The response returned by `IntoResponse::into_response` must use
`axum::body::Body` as the body type. `axum::response::Response` does this
([#1789])
- **breaking:** Removed the `BoxBody` type alias and its `box_body`
constructor. Use `axum::body::Body::new` instead ([#1789])
- **breaking:** Remove `RawBody` extractor. `axum::body::Body` implements `FromRequest` directly ([#1789])
- **added:** Add `axum::extract::Request` type alias where the body is `axum::body::Body` ([#1789])
- **added:** Add `Router::as_service` and `Router::into_service` to workaround
type inference issues when calling `ServiceExt` methods on a `Router` ([#1835])
@ -35,6 +45,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#1751]: https://github.com/tokio-rs/axum/pull/1751
[#1762]: https://github.com/tokio-rs/axum/pull/1762
[#1835]: https://github.com/tokio-rs/axum/pull/1835
[#1789]: https://github.com/tokio-rs/axum/pull/1789
# 0.6.16 (18. April, 2023)

View File

@ -1,10 +1,10 @@
//! HTTP body utilities.
#[doc(no_inline)]
pub use http_body::{Body as HttpBody, Empty, Full};
pub use http_body::Body as HttpBody;
#[doc(no_inline)]
pub use bytes::Bytes;
#[doc(inline)]
pub use axum_core::body::{boxed, Body, BoxBody};
pub use axum_core::body::Body;

View File

@ -1,8 +1,9 @@
use crate::{
body::{self, Bytes, HttpBody},
body::{Bytes, HttpBody},
response::{IntoResponse, Response},
BoxError, Error,
};
use axum_core::body::Body;
use futures_util::{
ready,
stream::{self, TryStream},
@ -93,7 +94,7 @@ where
S::Error: Into<BoxError>,
{
fn into_response(self) -> Response {
Response::new(body::boxed(self))
Response::new(Body::new(self))
}
}

View File

@ -1,7 +1,6 @@
use std::{convert::Infallible, fmt};
use axum_core::body::Body;
use http::Request;
use crate::extract::Request;
use tower::Service;
use crate::{
@ -64,7 +63,7 @@ pub(crate) trait ErasedIntoRoute<S, E>: Send {
fn into_route(self: Box<Self>, state: S) -> Route<E>;
fn call_with_state(self: Box<Self>, request: Request<Body>, state: S) -> RouteFuture<E>;
fn call_with_state(self: Box<Self>, request: Request, state: S) -> RouteFuture<E>;
}
pub(crate) struct MakeErasedHandler<H, S> {
@ -85,11 +84,7 @@ where
(self.into_route)(self.handler, state)
}
fn call_with_state(
self: Box<Self>,
request: Request<Body>,
state: S,
) -> RouteFuture<Infallible> {
fn call_with_state(self: Box<Self>, request: Request, state: S) -> RouteFuture<Infallible> {
self.into_route(state).call(request)
}
}
@ -123,11 +118,7 @@ where
(self.into_route)(self.router, state)
}
fn call_with_state(
mut self: Box<Self>,
request: Request<Body>,
state: S,
) -> RouteFuture<Infallible> {
fn call_with_state(mut self: Box<Self>, request: Request, state: S) -> RouteFuture<Infallible> {
self.router.call_with_state(request, state)
}
}
@ -166,7 +157,7 @@ where
(self.layer)(self.inner.into_route(state))
}
fn call_with_state(self: Box<Self>, request: Request<Body>, state: S) -> RouteFuture<E2> {
fn call_with_state(self: Box<Self>, request: Request, state: S) -> RouteFuture<E2> {
(self.layer)(self.inner.into_route(state)).call(request)
}
}

View File

@ -58,10 +58,10 @@ Some commonly used extractors are:
```rust,no_run
use axum::{
extract::{Json, TypedHeader, Path, Extension, Query},
extract::{Request, Json, TypedHeader, Path, Extension, Query},
routing::post,
headers::UserAgent,
http::{Request, header::HeaderMap},
http::header::HeaderMap,
body::{Bytes, Body},
Router,
};
@ -92,7 +92,7 @@ async fn bytes(body: Bytes) {}
async fn json(Json(payload): Json<Value>) {}
// `Request` gives you the whole request for maximum control
async fn request(request: Request<Body>) {}
async fn request(request: Request) {}
// `Extension` extracts data from "request extensions"
// This is commonly used to share state with handlers
@ -464,7 +464,7 @@ If your extractor needs to consume the request body you must implement [`FromReq
```rust,no_run
use axum::{
async_trait,
extract::FromRequest,
extract::{Request, FromRequest},
response::{Response, IntoResponse},
body::{Bytes, Body},
routing::get,
@ -472,7 +472,6 @@ use axum::{
http::{
StatusCode,
header::{HeaderValue, USER_AGENT},
Request,
},
};
@ -486,7 +485,7 @@ where
{
type Rejection = Response;
async fn from_request(req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
let body = Bytes::from_request(req, state)
.await
.map_err(IntoResponse::into_response)?;
@ -517,8 +516,8 @@ wrapping another extractor:
use axum::{
Router,
routing::get,
extract::{FromRequest, FromRequestParts},
http::{Request, request::Parts},
extract::{FromRequest, Request, FromRequestParts},
http::request::Parts,
body::Body,
async_trait,
};
@ -535,7 +534,7 @@ where
{
type Rejection = Infallible;
async fn from_request(req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
// ...
# todo!()
}
@ -645,20 +644,17 @@ Extractors can also be run from middleware:
```rust
use axum::{
middleware::{self, Next},
extract::{TypedHeader, FromRequestParts},
http::{Request, StatusCode},
extract::{TypedHeader, Request, FromRequestParts},
http::StatusCode,
response::Response,
headers::authorization::{Authorization, Bearer},
RequestPartsExt, Router,
};
async fn auth_middleware<B>(
request: Request<B>,
next: Next<B>,
) -> Result<Response, StatusCode>
where
B: Send,
{
async fn auth_middleware(
request: Request,
next: Next,
) -> Result<Response, StatusCode> {
// running extractors requires a `axum::http::request::Parts`
let (mut parts, body) = request.into_parts();
@ -697,8 +693,8 @@ use axum::{
Router,
body::Body,
routing::get,
extract::{FromRequest, FromRequestParts},
http::{Request, HeaderMap, request::Parts},
extract::{Request, FromRequest, FromRequestParts},
http::{HeaderMap, request::Parts},
async_trait,
};
use std::time::{Instant, Duration};
@ -738,7 +734,7 @@ where
{
type Rejection = T::Rejection;
async fn from_request(req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
let start = Instant::now();
let extractor = T::from_request(req, state).await?;
let duration = start.elapsed();

View File

@ -223,7 +223,7 @@ A decent template for such a middleware could be:
use axum::{
response::Response,
body::Body,
http::Request,
extract::Request,
};
use futures_util::future::BoxFuture;
use tower::{Service, Layer};
@ -245,9 +245,9 @@ struct MyMiddleware<S> {
inner: S,
}
impl<S> Service<Request<Body>> for MyMiddleware<S>
impl<S> Service<Request> for MyMiddleware<S>
where
S: Service<Request<Body>, Response = Response> + Send + 'static,
S: Service<Request, Response = Response> + Send + 'static,
S::Future: Send + 'static,
{
type Response = S::Response;
@ -259,7 +259,7 @@ where
self.inner.poll_ready(cx)
}
fn call(&mut self, request: Request<Body>) -> Self::Future {
fn call(&mut self, request: Request) -> Self::Future {
let future = self.inner.call(request);
Box::pin(async move {
let response: Response = future.await?;
@ -406,8 +406,7 @@ use axum::{
routing::get,
middleware::{self, Next},
response::Response,
extract::State,
http::Request,
extract::{State, Request},
};
use tower::{Layer, Service};
use std::task::{Context, Poll};
@ -477,17 +476,17 @@ State can be passed from middleware to handlers using [request extensions]:
```rust
use axum::{
Router,
http::{Request, StatusCode},
http::StatusCode,
routing::get,
response::{IntoResponse, Response},
middleware::{self, Next},
extract::Extension,
extract::{Request, Extension},
};
#[derive(Clone)]
struct CurrentUser { /* ... */ }
async fn auth<B>(mut req: Request<B>, next: Next<B>) -> Result<Response, StatusCode> {
async fn auth(mut req: Request, next: Next) -> Result<Response, StatusCode> {
let auth_header = req.headers()
.get(http::header::AUTHORIZATION)
.and_then(|header| header.to_str().ok());
@ -546,7 +545,7 @@ use axum::{
ServiceExt, // for `into_make_service`
response::Response,
middleware::Next,
http::Request,
extract::Request,
};
fn rewrite_request_uri<B>(req: Request<B>) -> Request<B> {

View File

@ -171,15 +171,15 @@ Use [`Response`](crate::response::Response) for more low level control:
use axum::{
Json,
response::{IntoResponse, Response},
body::{Full, Bytes},
body::Body,
http::StatusCode,
};
async fn response() -> Response<Full<Bytes>> {
async fn response() -> Response {
Response::builder()
.status(StatusCode::NOT_FOUND)
.header("x-foo", "custom header")
.body(Full::from("not found"))
.body(Body::from("not found"))
.unwrap()
}
```

View File

@ -7,7 +7,8 @@ use axum::{
Router,
body::Body,
routing::{any_service, get_service},
http::{Request, StatusCode},
extract::Request,
http::StatusCode,
error_handling::HandleErrorLayer,
};
use tower_http::services::ServeFile;
@ -22,7 +23,7 @@ let app = Router::new()
// Services whose response body is not `axum::body::BoxBody`
// can be wrapped in `axum::routing::any_service` (or one of the other routing filters)
// to have the response body mapped
any_service(service_fn(|_: Request<Body>| async {
any_service(service_fn(|_: Request| async {
let res = Response::new(Body::from("Hi from `GET /`"));
Ok::<_, Infallible>(res)
}))
@ -31,9 +32,8 @@ let app = Router::new()
"/foo",
// This service's response body is `axum::body::BoxBody` so
// it can be routed to directly.
service_fn(|req: Request<Body>| async move {
service_fn(|req: Request| async move {
let body = Body::from(format!("Hi from `{} /foo`", req.method()));
let body = axum::body::boxed(body);
let res = Response::new(body);
Ok::<_, Infallible>(res)
})

View File

@ -35,8 +35,7 @@ use std::{collections::HashMap, sync::Arc};
/// ```
/// use axum::{
/// Router,
/// extract::MatchedPath,
/// http::Request,
/// extract::{Request, MatchedPath},
/// routing::get,
/// };
/// use tower_http::trace::TraceLayer;
@ -65,13 +64,12 @@ use std::{collections::HashMap, sync::Arc};
/// Router,
/// RequestExt,
/// routing::get,
/// extract::{MatchedPath, rejection::MatchedPathRejection},
/// extract::{Request, MatchedPath, rejection::MatchedPathRejection},
/// middleware::map_request,
/// http::Request,
/// body::Body,
/// };
///
/// async fn access_matched_path(mut request: Request<Body>) -> Request<Body> {
/// async fn access_matched_path(mut request: Request) -> Request {
/// // if `/foo/bar` is called this will be `Err(_)` since that matches
/// // a nested route
/// let matched_path: Result<MatchedPath, MatchedPathRejection> =

View File

@ -17,7 +17,7 @@ mod request_parts;
mod state;
#[doc(inline)]
pub use axum_core::extract::{DefaultBodyLimit, FromRef, FromRequest, FromRequestParts};
pub use axum_core::extract::{DefaultBodyLimit, FromRef, FromRequest, FromRequestParts, Request};
#[cfg(feature = "macros")]
pub use axum_macros::{FromRef, FromRequest, FromRequestParts};
@ -29,7 +29,6 @@ pub use self::{
path::{Path, RawPathParams},
raw_form::RawForm,
raw_query::RawQuery,
request_parts::RawBody,
state::State,
};

View File

@ -2,7 +2,7 @@
//!
//! See [`Multipart`] for more details.
use super::FromRequest;
use super::{FromRequest, Request};
use crate::body::Bytes;
use async_trait::async_trait;
use axum_core::__composite_rejection as composite_rejection;
@ -12,7 +12,7 @@ use axum_core::body::Body;
use axum_core::RequestExt;
use futures_util::stream::Stream;
use http::header::{HeaderMap, CONTENT_TYPE};
use http::{Request, StatusCode};
use http::StatusCode;
use std::error::Error;
use std::{
fmt,
@ -65,7 +65,7 @@ where
{
type Rejection = MultipartRejection;
async fn from_request(req: Request<Body>, _state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, _state: &S) -> Result<Self, Self::Rejection> {
let boundary = parse_boundary(req.headers()).ok_or(InvalidBoundary)?;
let stream = match req.with_limited_body() {
Ok(limited) => Body::new(limited),

View File

@ -1,7 +1,7 @@
use async_trait::async_trait;
use axum_core::{body::Body, extract::FromRequest};
use axum_core::extract::{FromRequest, Request};
use bytes::{Bytes, BytesMut};
use http::{Method, Request};
use http::Method;
use super::{
has_content_type,
@ -39,7 +39,7 @@ where
{
type Rejection = RawFormRejection;
async fn from_request(req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
if req.method() == Method::GET {
let mut bytes = BytesMut::new();

View File

@ -1,7 +1,6 @@
use super::{Extension, FromRequest, FromRequestParts};
use crate::body::Body;
use super::{Extension, FromRequestParts};
use async_trait::async_trait;
use http::{request::Parts, Request, Uri};
use http::{request::Parts, Uri};
use std::convert::Infallible;
/// Extractor that gets the original request URI regardless of nesting.
@ -94,49 +93,6 @@ where
#[cfg(feature = "original-uri")]
axum_core::__impl_deref!(OriginalUri: Uri);
/// Extractor that extracts the raw request body.
///
/// Since extracting the raw request body requires consuming it, the `RawBody` extractor must be
/// *last* if there are multiple extractors in a handler. See ["the order of extractors"][order-of-extractors]
///
/// [order-of-extractors]: crate::extract#the-order-of-extractors
///
/// # Example
///
/// ```rust,no_run
/// use axum::{
/// extract::RawBody,
/// routing::get,
/// Router,
/// };
/// use futures_util::StreamExt;
///
/// async fn handler(RawBody(body): RawBody) {
/// // ...
/// }
///
/// let app = Router::new().route("/users", get(handler));
/// # async {
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
/// # };
/// ```
///
/// [`body::Body`]: crate::body::Body
#[derive(Debug, Default)]
pub struct RawBody(pub Body);
#[async_trait]
impl<S> FromRequest<S> for RawBody
where
S: Send + Sync,
{
type Rejection = Infallible;
async fn from_request(req: Request<Body>, _state: &S) -> Result<Self, Self::Rejection> {
Ok(Self(req.into_body()))
}
}
#[cfg(test)]
mod tests {
use crate::{extract::Extension, routing::get, test_helpers::*, Router};

View File

@ -96,12 +96,9 @@
use self::rejection::*;
use super::FromRequestParts;
use crate::{
body::{self, Bytes},
response::Response,
Error,
};
use crate::{body::Bytes, response::Response, Error};
use async_trait::async_trait;
use axum_core::body::Body;
use futures_util::{
sink::{Sink, SinkExt},
stream::{Stream, StreamExt},
@ -332,7 +329,7 @@ impl<F> WebSocketUpgrade<F> {
builder = builder.header(header::SEC_WEBSOCKET_PROTOCOL, protocol);
}
builder.body(body::boxed(body::Empty::new())).unwrap()
builder.body(Body::empty()).unwrap()
}
}

View File

@ -1,10 +1,10 @@
use crate::extract::Request;
use crate::extract::{rejection::*, FromRequest, RawForm};
use async_trait::async_trait;
use axum_core::body::Body;
use axum_core::response::{IntoResponse, Response};
use axum_core::RequestExt;
use http::header::CONTENT_TYPE;
use http::{Request, StatusCode};
use http::StatusCode;
use serde::de::DeserializeOwned;
use serde::Serialize;
@ -70,7 +70,7 @@ where
{
type Rejection = FormRejection;
async fn from_request(req: Request<Body>, _state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, _state: &S) -> Result<Self, Self::Rejection> {
let is_get_or_head =
req.method() == http::Method::GET || req.method() == http::Method::HEAD;
@ -114,14 +114,15 @@ axum_core::__impl_deref!(Form);
#[cfg(test)]
mod tests {
use super::*;
use crate::{
body::Body,
routing::{on, MethodFilter},
test_helpers::TestClient,
Router,
};
use http::{header::CONTENT_TYPE, Method, Request};
use super::*;
use axum_core::body::Body;
use http::{Method, Request};
use mime::APPLICATION_WWW_FORM_URLENCODED;
use serde::{Deserialize, Serialize};
use std::fmt::Debug;

View File

@ -1,9 +1,8 @@
//! Handler future types.
use crate::body::Body;
use crate::response::Response;
use axum_core::extract::Request;
use futures_util::future::Map;
use http::Request;
use pin_project_lite::pin_project;
use std::{convert::Infallible, future::Future, pin::Pin, task::Context};
use tower::util::Oneshot;
@ -22,19 +21,19 @@ pin_project! {
/// The response future for [`Layered`](super::Layered).
pub struct LayeredFuture<S>
where
S: Service<Request<Body>>,
S: Service<Request>,
{
#[pin]
inner: Map<Oneshot<S, Request<Body>>, fn(Result<S::Response, S::Error>) -> Response>,
inner: Map<Oneshot<S, Request>, fn(Result<S::Response, S::Error>) -> Response>,
}
}
impl<S> LayeredFuture<S>
where
S: Service<Request<Body>>,
S: Service<Request>,
{
pub(super) fn new(
inner: Map<Oneshot<S, Request<Body>>, fn(Result<S::Response, S::Error>) -> Response>,
inner: Map<Oneshot<S, Request>, fn(Result<S::Response, S::Error>) -> Response>,
) -> Self {
Self { inner }
}
@ -42,7 +41,7 @@ where
impl<S> Future for LayeredFuture<S>
where
S: Service<Request<Body>>,
S: Service<Request>,
{
type Output = Response;

View File

@ -37,12 +37,10 @@
#[cfg(feature = "tokio")]
use crate::extract::connect_info::IntoMakeServiceWithConnectInfo;
use crate::{
extract::{FromRequest, FromRequestParts},
extract::{FromRequest, FromRequestParts, Request},
response::{IntoResponse, Response},
routing::IntoMakeService,
};
use axum_core::body::Body;
use http::Request;
use std::{convert::Infallible, fmt, future::Future, marker::PhantomData, pin::Pin};
use tower::ServiceExt;
use tower_layer::Layer;
@ -68,9 +66,8 @@ pub use self::service::HandlerService;
/// ```
/// use tower::Service;
/// use axum::{
/// extract::State,
/// extract::{State, Request},
/// body::Body,
/// http::Request,
/// handler::{HandlerWithoutStateExt, Handler},
/// };
///
@ -89,7 +86,7 @@ pub use self::service::HandlerService;
/// // helper to check that a value implements `Service`
/// fn assert_service<S>(service: S)
/// where
/// S: Service<Request<Body>>,
/// S: Service<Request>,
/// {}
/// ```
#[doc = include_str!("../docs/debugging_handler_type_errors.md")]
@ -104,7 +101,7 @@ pub trait Handler<T, S>: Clone + Send + Sized + 'static {
type Future: Future<Output = Response> + Send + 'static;
/// Call the handler with the given request.
fn call(self, req: Request<Body>, state: S) -> Self::Future;
fn call(self, req: Request, state: S) -> Self::Future;
/// Apply a [`tower::Layer`] to the handler.
///
@ -145,7 +142,7 @@ pub trait Handler<T, S>: Clone + Send + Sized + 'static {
fn layer<L>(self, layer: L) -> Layered<L, Self, T, S>
where
L: Layer<HandlerService<Self, T, S>> + Clone,
L::Service: Service<Request<Body>>,
L::Service: Service<Request>,
{
Layered {
layer,
@ -168,7 +165,7 @@ where
{
type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
fn call(self, _req: Request<Body>, _state: S) -> Self::Future {
fn call(self, _req: Request, _state: S) -> Self::Future {
Box::pin(async move { self().await.into_response() })
}
}
@ -189,7 +186,7 @@ macro_rules! impl_handler {
{
type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
fn call(self, req: Request<Body>, state: S) -> Self::Future {
fn call(self, req: Request, state: S) -> Self::Future {
Box::pin(async move {
let (mut parts, body) = req.into_parts();
let state = &state;
@ -257,15 +254,15 @@ impl<H, S, T, L> Handler<T, S> for Layered<L, H, T, S>
where
L: Layer<HandlerService<H, T, S>> + Clone + Send + 'static,
H: Handler<T, S>,
L::Service: Service<Request<Body>, Error = Infallible> + Clone + Send + 'static,
<L::Service as Service<Request<Body>>>::Response: IntoResponse,
<L::Service as Service<Request<Body>>>::Future: Send,
L::Service: Service<Request, Error = Infallible> + Clone + Send + 'static,
<L::Service as Service<Request>>::Response: IntoResponse,
<L::Service as Service<Request>>::Future: Send,
T: 'static,
S: 'static,
{
type Future = future::LayeredFuture<L::Service>;
fn call(self, req: Request<Body>, state: S) -> Self::Future {
fn call(self, req: Request, state: S) -> Self::Future {
use futures_util::future::{FutureExt, Map};
let svc = self.handler.with_state(state);
@ -275,8 +272,8 @@ where
_,
fn(
Result<
<L::Service as Service<Request<Body>>>::Response,
<L::Service as Service<Request<Body>>>::Error,
<L::Service as Service<Request>>::Response,
<L::Service as Service<Request>>::Error,
>,
) -> _,
> = svc.oneshot(req).map(|result| match result {
@ -339,7 +336,8 @@ where
#[cfg(test)]
mod tests {
use super::*;
use crate::{body, extract::State, test_helpers::*};
use crate::{extract::State, test_helpers::*};
use axum_core::body::Body;
use http::StatusCode;
use std::time::Duration;
use tower_http::{
@ -371,10 +369,10 @@ mod tests {
.layer((
RequestBodyLimitLayer::new(1024),
TimeoutLayer::new(Duration::from_secs(10)),
MapResponseBodyLayer::new(body::boxed),
MapResponseBodyLayer::new(Body::new),
CompressionLayer::new(),
))
.layer(MapRequestBodyLayer::new(body::boxed))
.layer(MapRequestBodyLayer::new(Body::new))
.with_state("foo");
let client = TestClient::new(svc);

View File

@ -1,13 +1,11 @@
use crate::extract::Request;
use crate::extract::{rejection::*, FromRequest};
use async_trait::async_trait;
use axum_core::{
body::Body,
response::{IntoResponse, Response},
};
use axum_core::response::{IntoResponse, Response};
use bytes::{BufMut, Bytes, BytesMut};
use http::{
header::{self, HeaderMap, HeaderValue},
Request, StatusCode,
StatusCode,
};
use serde::{de::DeserializeOwned, Serialize};
@ -106,7 +104,7 @@ where
{
type Rejection = JsonRejection;
async fn from_request(req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
if json_content_type(req.headers()) {
let bytes = Bytes::from_request(req, state).await?;
let deserializer = &mut serde_json::Deserializer::from_slice(&bytes);

View File

@ -1,9 +1,6 @@
use crate::body::{Body, Bytes, HttpBody};
use crate::response::{IntoResponse, Response};
use crate::BoxError;
use axum_core::extract::{FromRequest, FromRequestParts};
use axum_core::extract::{FromRequest, FromRequestParts, Request};
use futures_util::future::BoxFuture;
use http::Request;
use std::{
any::type_name,
convert::Infallible,
@ -23,7 +20,7 @@ use tower_service::Service;
///
/// 1. Be an `async fn`.
/// 2. Take one or more [extractors] as the first arguments.
/// 3. Take [`Next<B>`](Next) as the final argument.
/// 3. Take [`Next`](Next) as the final argument.
/// 4. Return something that implements [`IntoResponse`].
///
/// Note that this function doesn't support extracting [`State`]. For that, use [`from_fn_with_state`].
@ -33,15 +30,16 @@ use tower_service::Service;
/// ```rust
/// use axum::{
/// Router,
/// http::{self, Request},
/// http,
/// routing::get,
/// response::Response,
/// middleware::{self, Next},
/// extract::Request,
/// };
///
/// async fn my_middleware<B>(
/// request: Request<B>,
/// next: Next<B>,
/// async fn my_middleware(
/// request: Request,
/// next: Next,
/// ) -> Response {
/// // do something with `request`...
///
@ -63,23 +61,22 @@ use tower_service::Service;
/// ```rust
/// use axum::{
/// Router,
/// extract::TypedHeader,
/// extract::{Request, TypedHeader},
/// http::StatusCode,
/// headers::authorization::{Authorization, Bearer},
/// http::Request,
/// middleware::{self, Next},
/// response::Response,
/// routing::get,
/// };
///
/// async fn auth<B>(
/// async fn auth(
/// // run the `TypedHeader` extractor
/// TypedHeader(auth): TypedHeader<Authorization<Bearer>>,
/// // you can also add more extractors here but the last
/// // extractor must implement `FromRequest` which
/// // `Request` does
/// request: Request<B>,
/// next: Next<B>,
/// request: Request,
/// next: Next,
/// ) -> Result<Response, StatusCode> {
/// if token_is_valid(auth.token()) {
/// let response = next.run(request).await;
@ -115,23 +112,23 @@ pub fn from_fn<F, T>(f: F) -> FromFnLayer<F, (), T> {
/// ```rust
/// use axum::{
/// Router,
/// http::{Request, StatusCode},
/// http::StatusCode,
/// routing::get,
/// response::{IntoResponse, Response},
/// middleware::{self, Next},
/// extract::State,
/// extract::{Request, State},
/// };
///
/// #[derive(Clone)]
/// struct AppState { /* ... */ }
///
/// async fn my_middleware<B>(
/// async fn my_middleware(
/// State(state): State<AppState>,
/// // you can add more extractors here but the last
/// // extractor must implement `FromRequest` which
/// // `Request` does
/// request: Request<B>,
/// next: Next<B>,
/// request: Request,
/// next: Next,
/// ) -> Response {
/// // do something with `request`...
///
@ -245,21 +242,19 @@ macro_rules! impl_service {
[$($ty:ident),*], $last:ident
) => {
#[allow(non_snake_case, unused_mut)]
impl<F, Fut, Out, S, I, B, $($ty,)* $last> Service<Request<B>> for FromFn<F, S, I, ($($ty,)* $last,)>
impl<F, Fut, Out, S, I, $($ty,)* $last> Service<Request> for FromFn<F, S, I, ($($ty,)* $last,)>
where
F: FnMut($($ty,)* $last, Next<B>) -> Fut + Clone + Send + 'static,
F: FnMut($($ty,)* $last, Next) -> Fut + Clone + Send + 'static,
$( $ty: FromRequestParts<S> + Send, )*
$last: FromRequest<S> + Send,
Fut: Future<Output = Out> + Send + 'static,
Out: IntoResponse + 'static,
I: Service<Request<B>, Error = Infallible>
I: Service<Request, Error = Infallible>
+ Clone
+ Send
+ 'static,
I::Response: IntoResponse,
I::Future: Send + 'static,
B: HttpBody<Data = Bytes> + Send + 'static,
B::Error: Into<BoxError>,
S: Clone + Send + Sync + 'static,
{
type Response = Response;
@ -270,9 +265,7 @@ macro_rules! impl_service {
self.inner.poll_ready(cx)
}
fn call(&mut self, req: Request<B>) -> Self::Future {
let req = req.map(Body::new);
fn call(&mut self, req: Request) -> Self::Future {
let not_ready_inner = self.inner.clone();
let ready_inner = std::mem::replace(&mut self.inner, not_ready_inner);
@ -330,13 +323,14 @@ where
}
/// The remainder of a middleware stack, including the handler.
pub struct Next<B> {
inner: BoxCloneService<Request<B>, Response, Infallible>,
#[derive(Debug, Clone)]
pub struct Next {
inner: BoxCloneService<Request, Response, Infallible>,
}
impl<B> Next<B> {
impl Next {
/// Execute the remaining middleware stack.
pub async fn run(mut self, req: Request<B>) -> Response {
pub async fn run(mut self, req: Request) -> Response {
match self.inner.call(req).await {
Ok(res) => res,
Err(err) => match err {},
@ -344,23 +338,7 @@ impl<B> Next<B> {
}
}
impl<B> fmt::Debug for Next<B> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FromFnLayer")
.field("inner", &self.inner)
.finish()
}
}
impl<B> Clone for Next<B> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}
impl<B> Service<Request<B>> for Next<B> {
impl Service<Request> for Next {
type Response = Response;
type Error = Infallible;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
@ -369,7 +347,7 @@ impl<B> Service<Request<B>> for Next<B> {
self.inner.poll_ready(cx)
}
fn call(&mut self, req: Request<B>) -> Self::Future {
fn call(&mut self, req: Request) -> Self::Future {
self.inner.call(req)
}
}
@ -402,7 +380,7 @@ mod tests {
#[crate::test]
async fn basic() {
async fn insert_header<B>(mut req: Request<B>, next: Next<B>) -> impl IntoResponse {
async fn insert_header(mut req: Request, next: Next) -> impl IntoResponse {
req.headers_mut()
.insert("x-axum-test", "ok".parse().unwrap());

View File

@ -1,6 +1,6 @@
#![doc = include_str!("../docs/response.md")]
use crate::body::{Bytes, Full};
use axum_core::body::Body;
use http::{header, HeaderValue};
mod redirect;
@ -44,7 +44,7 @@ pub struct Html<T>(pub T);
impl<T> IntoResponse for Html<T>
where
T: Into<Full<Bytes>>,
T: Into<Body>,
{
fn into_response(self) -> Response {
(

View File

@ -32,7 +32,7 @@ use crate::{
BoxError,
};
use axum_core::{
body,
body::Body,
response::{IntoResponse, Response},
};
use bytes::{BufMut, BytesMut};
@ -104,7 +104,7 @@ where
(http::header::CONTENT_TYPE, mime::TEXT_EVENT_STREAM.as_ref()),
(http::header::CACHE_CONTROL, "no-cache"),
],
body::boxed(Body {
Body::new(SseBody {
event_stream: SyncWrapper::new(self.stream),
keep_alive: self.keep_alive.map(KeepAliveStream::new),
}),
@ -114,7 +114,7 @@ where
}
pin_project! {
struct Body<S> {
struct SseBody<S> {
#[pin]
event_stream: SyncWrapper<S>,
#[pin]
@ -122,7 +122,7 @@ pin_project! {
}
}
impl<S, E> HttpBody for Body<S>
impl<S, E> HttpBody for SseBody<S>
where
S: Stream<Item = Result<Event, E>>,
{

View File

@ -46,12 +46,11 @@ opaque_future! {
#[cfg(test)]
mod tests {
use super::*;
use crate::body::Body;
#[test]
fn traits() {
use crate::test_helpers::*;
assert_send::<IntoMakeService<Body>>();
assert_send::<IntoMakeService<()>>();
}
}

View File

@ -8,11 +8,11 @@ use crate::{
boxed::BoxedIntoRoute,
error_handling::{HandleError, HandleErrorLayer},
handler::Handler,
http::{Method, Request, StatusCode},
http::{Method, StatusCode},
response::Response,
routing::{future::RouteFuture, Fallback, MethodFilter, Route},
};
use axum_core::{response::IntoResponse, BoxError};
use axum_core::{extract::Request, response::IntoResponse, BoxError};
use bytes::BytesMut;
use std::{
convert::Infallible,
@ -34,7 +34,7 @@ macro_rules! top_level_service_fn {
///
/// ```rust
/// use axum::{
/// http::Request,
/// extract::Request,
/// Router,
/// routing::get_service,
/// body::Body,
@ -42,7 +42,7 @@ macro_rules! top_level_service_fn {
/// use http::Response;
/// use std::convert::Infallible;
///
/// let service = tower::service_fn(|request: Request<Body>| async {
/// let service = tower::service_fn(|request: Request| async {
/// Ok::<_, Infallible>(Response::new(Body::empty()))
/// });
///
@ -80,7 +80,7 @@ macro_rules! top_level_service_fn {
$(#[$m])+
pub fn $name<T, S>(svc: T) -> MethodRouter<S, T::Error>
where
T: Service<Request<Body>> + Clone + Send + 'static,
T: Service<Request> + Clone + Send + 'static,
T::Response: IntoResponse + 'static,
T::Future: Send + 'static,
S: Clone,
@ -161,7 +161,7 @@ macro_rules! chained_service_fn {
///
/// ```rust
/// use axum::{
/// http::Request,
/// extract::Request,
/// Router,
/// routing::post_service,
/// body::Body,
@ -169,11 +169,11 @@ macro_rules! chained_service_fn {
/// use http::Response;
/// use std::convert::Infallible;
///
/// let service = tower::service_fn(|request: Request<Body>| async {
/// let service = tower::service_fn(|request: Request| async {
/// Ok::<_, Infallible>(Response::new(Body::empty()))
/// });
///
/// let other_service = tower::service_fn(|request: Request<Body>| async {
/// let other_service = tower::service_fn(|request: Request| async {
/// Ok::<_, Infallible>(Response::new(Body::empty()))
/// });
///
@ -213,7 +213,7 @@ macro_rules! chained_service_fn {
#[track_caller]
pub fn $name<T>(self, svc: T) -> Self
where
T: Service<Request<Body>, Error = E>
T: Service<Request, Error = E>
+ Clone
+ Send
+ 'static,
@ -301,7 +301,7 @@ top_level_service_fn!(trace_service, TRACE);
///
/// ```rust
/// use axum::{
/// http::Request,
/// extract::Request,
/// routing::on,
/// Router,
/// body::Body,
@ -310,7 +310,7 @@ top_level_service_fn!(trace_service, TRACE);
/// use http::Response;
/// use std::convert::Infallible;
///
/// let service = tower::service_fn(|request: Request<Body>| async {
/// let service = tower::service_fn(|request: Request| async {
/// Ok::<_, Infallible>(Response::new(Body::empty()))
/// });
///
@ -322,7 +322,7 @@ top_level_service_fn!(trace_service, TRACE);
/// ```
pub fn on_service<T, S>(filter: MethodFilter, svc: T) -> MethodRouter<S, T::Error>
where
T: Service<Request<Body>> + Clone + Send + 'static,
T: Service<Request> + Clone + Send + 'static,
T::Response: IntoResponse + 'static,
T::Future: Send + 'static,
S: Clone,
@ -336,7 +336,7 @@ where
///
/// ```rust
/// use axum::{
/// http::Request,
/// extract::Request,
/// Router,
/// routing::any_service,
/// body::Body,
@ -344,7 +344,7 @@ where
/// use http::Response;
/// use std::convert::Infallible;
///
/// let service = tower::service_fn(|request: Request<Body>| async {
/// let service = tower::service_fn(|request: Request| async {
/// Ok::<_, Infallible>(Response::new(Body::empty()))
/// });
///
@ -359,7 +359,7 @@ where
///
/// ```rust
/// use axum::{
/// http::Request,
/// extract::Request,
/// Router,
/// routing::any_service,
/// body::Body,
@ -367,12 +367,12 @@ where
/// use http::Response;
/// use std::convert::Infallible;
///
/// let service = tower::service_fn(|request: Request<Body>| async {
/// let service = tower::service_fn(|request: Request| async {
/// # Ok::<_, Infallible>(Response::new(Body::empty()))
/// // ...
/// });
///
/// let other_service = tower::service_fn(|request: Request<Body>| async {
/// let other_service = tower::service_fn(|request: Request| async {
/// # Ok::<_, Infallible>(Response::new(Body::empty()))
/// // ...
/// });
@ -385,7 +385,7 @@ where
/// ```
pub fn any_service<T, S>(svc: T) -> MethodRouter<S, T::Error>
where
T: Service<Request<Body>> + Clone + Send + 'static,
T: Service<Request> + Clone + Send + 'static,
T::Response: IntoResponse + 'static,
T::Future: Send + 'static,
S: Clone,
@ -487,7 +487,7 @@ where
///
/// ```
/// use tower::Service;
/// use axum::{routing::get, extract::State, body::Body, http::Request};
/// use axum::{routing::get, extract::{State, Request}, body::Body};
///
/// // this `MethodRouter` doesn't require any state, i.e. the state is `()`,
/// let method_router = get(|| async {});
@ -504,7 +504,7 @@ where
/// // helper to check that a value implements `Service`
/// fn assert_service<S>(service: S)
/// where
/// S: Service<Request<Body>>,
/// S: Service<Request>,
/// {}
/// ```
#[must_use]
@ -703,7 +703,7 @@ where
/// Create a default `MethodRouter` that will respond with `405 Method Not Allowed` to all
/// requests.
pub fn new() -> Self {
let fallback = Route::new(service_fn(|_: Request<Body>| async {
let fallback = Route::new(service_fn(|_: Request| async {
Ok(StatusCode::METHOD_NOT_ALLOWED.into_response())
}));
@ -744,7 +744,7 @@ where
///
/// ```rust
/// use axum::{
/// http::Request,
/// extract::Request,
/// Router,
/// routing::{MethodFilter, on_service},
/// body::Body,
@ -752,7 +752,7 @@ where
/// use http::Response;
/// use std::convert::Infallible;
///
/// let service = tower::service_fn(|request: Request<Body>| async {
/// let service = tower::service_fn(|request: Request| async {
/// Ok::<_, Infallible>(Response::new(Body::empty()))
/// });
///
@ -765,7 +765,7 @@ where
#[track_caller]
pub fn on_service<T>(self, filter: MethodFilter, svc: T) -> Self
where
T: Service<Request<Body>, Error = E> + Clone + Send + 'static,
T: Service<Request, Error = E> + Clone + Send + 'static,
T::Response: IntoResponse + 'static,
T::Future: Send + 'static,
{
@ -897,7 +897,7 @@ where
#[doc = include_str!("../docs/method_routing/fallback.md")]
pub fn fallback_service<T>(mut self, svc: T) -> Self
where
T: Service<Request<Body>, Error = E> + Clone + Send + 'static,
T: Service<Request, Error = E> + Clone + Send + 'static,
T::Response: IntoResponse + 'static,
T::Future: Send + 'static,
{
@ -909,10 +909,10 @@ where
pub fn layer<L, NewError>(self, layer: L) -> MethodRouter<S, NewError>
where
L: Layer<Route<E>> + Clone + Send + 'static,
L::Service: Service<Request<Body>> + Clone + Send + 'static,
<L::Service as Service<Request<Body>>>::Response: IntoResponse + 'static,
<L::Service as Service<Request<Body>>>::Error: Into<NewError> + 'static,
<L::Service as Service<Request<Body>>>::Future: Send + 'static,
L::Service: Service<Request> + Clone + Send + 'static,
<L::Service as Service<Request>>::Response: IntoResponse + 'static,
<L::Service as Service<Request>>::Error: Into<NewError> + 'static,
<L::Service as Service<Request>>::Future: Send + 'static,
E: 'static,
S: 'static,
NewError: 'static,
@ -938,9 +938,9 @@ where
pub fn route_layer<L>(mut self, layer: L) -> MethodRouter<S, E>
where
L: Layer<Route<E>> + Clone + Send + 'static,
L::Service: Service<Request<Body>, Error = E> + Clone + Send + 'static,
<L::Service as Service<Request<Body>>>::Response: IntoResponse + 'static,
<L::Service as Service<Request<Body>>>::Future: Send + 'static,
L::Service: Service<Request, Error = E> + Clone + Send + 'static,
<L::Service as Service<Request>>::Response: IntoResponse + 'static,
<L::Service as Service<Request>>::Future: Send + 'static,
E: 'static,
S: 'static,
{
@ -1036,9 +1036,9 @@ where
pub fn handle_error<F, T>(self, f: F) -> MethodRouter<S, Infallible>
where
F: Clone + Send + Sync + 'static,
HandleError<Route<E>, F, T>: Service<Request<Body>, Error = Infallible>,
<HandleError<Route<E>, F, T> as Service<Request<Body>>>::Future: Send,
<HandleError<Route<E>, F, T> as Service<Request<Body>>>::Response: IntoResponse + Send,
HandleError<Route<E>, F, T>: Service<Request, Error = Infallible>,
<HandleError<Route<E>, F, T> as Service<Request>>::Future: Send,
<HandleError<Route<E>, F, T> as Service<Request>>::Response: IntoResponse + Send,
T: 'static,
E: 'static,
S: 'static,
@ -1051,7 +1051,7 @@ where
self
}
pub(crate) fn call_with_state(&mut self, req: Request<Body>, state: S) -> RouteFuture<E> {
pub(crate) fn call_with_state(&mut self, req: Request, state: S) -> RouteFuture<E> {
macro_rules! call {
(
$req:expr,
@ -1256,7 +1256,7 @@ where
{
type Future = InfallibleRouteFuture;
fn call(mut self, req: Request<Body>, state: S) -> Self::Future {
fn call(mut self, req: Request, state: S) -> Self::Future {
InfallibleRouteFuture::new(self.call_with_state(req, state))
}
}
@ -1284,7 +1284,7 @@ mod tests {
#[crate::test]
async fn get_service_fn() {
async fn handle(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
async fn handle(_req: Request) -> Result<Response<Body>, Infallible> {
Ok(Response::new(Body::from("ok")))
}
@ -1545,7 +1545,7 @@ mod tests {
async fn call<S>(method: Method, svc: &mut S) -> (StatusCode, HeaderMap, String)
where
S: Service<Request<Body>, Error = Infallible>,
S: Service<Request, Error = Infallible>,
S::Response: IntoResponse,
{
let request = Request::builder()

View File

@ -9,8 +9,10 @@ use crate::{
handler::Handler,
util::try_downcast,
};
use axum_core::response::{IntoResponse, Response};
use http::Request;
use axum_core::{
extract::Request,
response::{IntoResponse, Response},
};
use std::{
convert::Infallible,
fmt,
@ -124,7 +126,7 @@ where
#[doc = include_str!("../docs/routing/route_service.md")]
pub fn route_service<T>(mut self, path: &str, service: T) -> Self
where
T: Service<Request<Body>, Error = Infallible> + Clone + Send + 'static,
T: Service<Request, Error = Infallible> + Clone + Send + 'static,
T::Response: IntoResponse,
T::Future: Send + 'static,
{
@ -164,7 +166,7 @@ where
#[track_caller]
pub fn nest_service<T>(mut self, path: &str, service: T) -> Self
where
T: Service<Request<Body>, Error = Infallible> + Clone + Send + 'static,
T: Service<Request, Error = Infallible> + Clone + Send + 'static,
T::Response: IntoResponse,
T::Future: Send + 'static,
{
@ -213,10 +215,10 @@ where
pub fn layer<L>(self, layer: L) -> Router<S>
where
L: Layer<Route> + Clone + Send + 'static,
L::Service: Service<Request<Body>> + Clone + Send + 'static,
<L::Service as Service<Request<Body>>>::Response: IntoResponse + 'static,
<L::Service as Service<Request<Body>>>::Error: Into<Infallible> + 'static,
<L::Service as Service<Request<Body>>>::Future: Send + 'static,
L::Service: Service<Request> + Clone + Send + 'static,
<L::Service as Service<Request>>::Response: IntoResponse + 'static,
<L::Service as Service<Request>>::Error: Into<Infallible> + 'static,
<L::Service as Service<Request>>::Future: Send + 'static,
{
Router {
path_router: self.path_router.layer(layer.clone()),
@ -230,10 +232,10 @@ where
pub fn route_layer<L>(self, layer: L) -> Self
where
L: Layer<Route> + Clone + Send + 'static,
L::Service: Service<Request<Body>> + Clone + Send + 'static,
<L::Service as Service<Request<Body>>>::Response: IntoResponse + 'static,
<L::Service as Service<Request<Body>>>::Error: Into<Infallible> + 'static,
<L::Service as Service<Request<Body>>>::Future: Send + 'static,
L::Service: Service<Request> + Clone + Send + 'static,
<L::Service as Service<Request>>::Response: IntoResponse + 'static,
<L::Service as Service<Request>>::Error: Into<Infallible> + 'static,
<L::Service as Service<Request>>::Future: Send + 'static,
{
Router {
path_router: self.path_router.route_layer(layer),
@ -258,7 +260,7 @@ where
/// See [`Router::fallback`] for more details.
pub fn fallback_service<T>(self, service: T) -> Self
where
T: Service<Request<Body>, Error = Infallible> + Clone + Send + 'static,
T: Service<Request, Error = Infallible> + Clone + Send + 'static,
T::Response: IntoResponse,
T::Future: Send + 'static,
{
@ -284,7 +286,7 @@ where
pub(crate) fn call_with_state(
&mut self,
mut req: Request<Body>,
mut req: Request,
state: S,
) -> RouteFuture<Infallible> {
// required for opaque routers to still inherit the fallback
@ -607,10 +609,10 @@ where
fn layer<L>(self, layer: L) -> Endpoint<S>
where
L: Layer<Route> + Clone + Send + 'static,
L::Service: Service<Request<Body>> + Clone + Send + 'static,
<L::Service as Service<Request<Body>>>::Response: IntoResponse + 'static,
<L::Service as Service<Request<Body>>>::Error: Into<Infallible> + 'static,
<L::Service as Service<Request<Body>>>::Future: Send + 'static,
L::Service: Service<Request> + Clone + Send + 'static,
<L::Service as Service<Request>>::Response: IntoResponse + 'static,
<L::Service as Service<Request>>::Error: Into<Infallible> + 'static,
<L::Service as Service<Request>>::Future: Send + 'static,
{
match self {
Endpoint::MethodRouter(method_router) => {

View File

@ -1,12 +1,12 @@
use crate::{
body::{boxed, Body, Empty, HttpBody},
body::{Body, HttpBody},
response::Response,
};
use axum_core::response::IntoResponse;
use axum_core::{extract::Request, response::IntoResponse};
use bytes::Bytes;
use http::{
header::{self, CONTENT_LENGTH},
HeaderMap, HeaderValue, Request,
HeaderMap, HeaderValue,
};
use pin_project_lite::pin_project;
use std::{
@ -27,12 +27,12 @@ use tower_service::Service;
///
/// You normally shouldn't need to care about this type. It's used in
/// [`Router::layer`](super::Router::layer).
pub struct Route<E = Infallible>(BoxCloneService<Request<Body>, Response, E>);
pub struct Route<E = Infallible>(BoxCloneService<Request, Response, E>);
impl<E> Route<E> {
pub(crate) fn new<T>(svc: T) -> Self
where
T: Service<Request<Body>, Error = E> + Clone + Send + 'static,
T: Service<Request, Error = E> + Clone + Send + 'static,
T::Response: IntoResponse + 'static,
T::Future: Send + 'static,
{
@ -43,18 +43,18 @@ impl<E> Route<E> {
pub(crate) fn oneshot_inner(
&mut self,
req: Request<Body>,
) -> Oneshot<BoxCloneService<Request<Body>, Response, E>, Request<Body>> {
req: Request,
) -> Oneshot<BoxCloneService<Request, Response, E>, Request> {
self.0.clone().oneshot(req)
}
pub(crate) fn layer<L, NewError>(self, layer: L) -> Route<NewError>
where
L: Layer<Route<E>> + Clone + Send + 'static,
L::Service: Service<Request<Body>> + Clone + Send + 'static,
<L::Service as Service<Request<Body>>>::Response: IntoResponse + 'static,
<L::Service as Service<Request<Body>>>::Error: Into<NewError> + 'static,
<L::Service as Service<Request<Body>>>::Future: Send + 'static,
L::Service: Service<Request> + Clone + Send + 'static,
<L::Service as Service<Request>>::Response: IntoResponse + 'static,
<L::Service as Service<Request>>::Error: Into<NewError> + 'static,
<L::Service as Service<Request>>::Future: Send + 'static,
NewError: 'static,
{
let layer = ServiceBuilder::new()
@ -117,8 +117,8 @@ pin_project! {
Future {
#[pin]
future: Oneshot<
BoxCloneService<Request<Body>, Response, E>,
Request<Body>,
BoxCloneService<Request, Response, E>,
Request,
>,
},
Response {
@ -129,7 +129,7 @@ pin_project! {
impl<E> RouteFuture<E> {
pub(crate) fn from_future(
future: Oneshot<BoxCloneService<Request<Body>, Response, E>, Request<Body>>,
future: Oneshot<BoxCloneService<Request, Response, E>, Request>,
) -> Self {
Self {
kind: RouteFutureKind::Future { future },
@ -173,7 +173,7 @@ impl<E> Future for RouteFuture<E> {
set_content_length(res.size_hint(), res.headers_mut());
let res = if *this.strip_body {
res.map(|_| boxed(Empty::new()))
res.map(|_| Body::empty())
} else {
res
};

View File

@ -45,7 +45,7 @@ mod for_services {
async fn get_handles_head() {
let app = Router::new().route(
"/",
get_service(service_fn(|_req: Request<Body>| async move {
get_service(service_fn(|_req: Request| async move {
Ok::<_, Infallible>(
([("x-some-header", "foobar")], "you shouldn't see this").into_response(),
)

View File

@ -195,13 +195,13 @@ async fn services() {
let app = Router::new()
.route(
"/foo",
get_service(service_fn(|_: Request<Body>| async {
get_service(service_fn(|_: Request| async {
Ok::<_, Infallible>(Response::new(Body::empty()))
})),
)
.merge(Router::new().route(
"/bar",
get_service(service_fn(|_: Request<Body>| async {
get_service(service_fn(|_: Request| async {
Ok::<_, Infallible>(Response::new(Body::empty()))
})),
));
@ -218,7 +218,7 @@ async fn services() {
async fn all_the_uris(
uri: Uri,
OriginalUri(original_uri): OriginalUri,
req: Request<Body>,
req: Request,
) -> impl IntoResponse {
Json(json!({
"uri": uri.to_string(),

View File

@ -1,22 +1,16 @@
use crate::{
body::{Body, Bytes, Empty},
body::{Body, Bytes},
error_handling::HandleErrorLayer,
extract::{self, DefaultBodyLimit, FromRef, Path, State},
handler::{Handler, HandlerWithoutStateExt},
response::IntoResponse,
routing::{
delete, get, get_service, on, on_service, patch, patch_service,
path_router::path_for_nested_route, post, MethodFilter,
},
test_helpers::{
tracing_helpers::{capture_tracing, TracingEvent},
*,
},
BoxError, Extension, Json, Router,
response::{IntoResponse, Response},
routing::{delete, get, get_service, on, on_service, patch, patch_service, post, MethodFilter, path_router::path_for_nested_route},
test_helpers::{*, tracing_helpers::{capture_tracing, TracingEvent}},
BoxError, Json, Router, Extension,
};
use axum_core::extract::Request;
use futures_util::stream::StreamExt;
use http::{header::ALLOW, header::CONTENT_LENGTH, HeaderMap, Request, Response, StatusCode, Uri};
use serde::Deserialize;
use http::{header::ALLOW, header::CONTENT_LENGTH, HeaderMap, StatusCode, Uri};
use serde_json::json;
use std::{
convert::Infallible,
@ -28,6 +22,7 @@ use std::{
use tower::{service_fn, timeout::TimeoutLayer, util::MapResponseLayer, ServiceBuilder};
use tower_http::{limit::RequestBodyLimitLayer, validate_request::ValidateRequestHeaderLayer};
use tower_service::Service;
use serde::Deserialize;
mod fallback;
mod get_to_head;
@ -37,15 +32,15 @@ mod nest;
#[crate::test]
async fn hello_world() {
async fn root(_: Request<Body>) -> &'static str {
async fn root(_: Request) -> &'static str {
"Hello, World!"
}
async fn foo(_: Request<Body>) -> &'static str {
async fn foo(_: Request) -> &'static str {
"foo"
}
async fn users_create(_: Request<Body>) -> &'static str {
async fn users_create(_: Request) -> &'static str {
"users#create"
}
@ -73,13 +68,12 @@ async fn routing() {
let app = Router::new()
.route(
"/users",
get(|_: Request<Body>| async { "users#index" })
.post(|_: Request<Body>| async { "users#create" }),
get(|_: Request| async { "users#index" }).post(|_: Request| async { "users#create" }),
)
.route("/users/:id", get(|_: Request<Body>| async { "users#show" }))
.route("/users/:id", get(|_: Request| async { "users#show" }))
.route(
"/users/:id/action",
get(|_: Request<Body>| async { "users#action" }),
get(|_: Request| async { "users#action" }),
);
let client = TestClient::new(app);
@ -109,12 +103,8 @@ async fn router_type_doesnt_change() {
let app: Router = Router::new()
.route(
"/",
on(MethodFilter::GET, |_: Request<Body>| async {
"hi from GET"
})
.on(MethodFilter::POST, |_: Request<Body>| async {
"hi from POST"
}),
on(MethodFilter::GET, |_: Request| async { "hi from GET" })
.on(MethodFilter::POST, |_: Request| async { "hi from POST" }),
)
.layer(tower_http::compression::CompressionLayer::new());
@ -134,22 +124,22 @@ async fn routing_between_services() {
use std::convert::Infallible;
use tower::service_fn;
async fn handle(_: Request<Body>) -> &'static str {
async fn handle(_: Request) -> &'static str {
"handler"
}
let app = Router::new()
.route(
"/one",
get_service(service_fn(|_: Request<Body>| async {
get_service(service_fn(|_: Request| async {
Ok::<_, Infallible>(Response::new(Body::from("one get")))
}))
.post_service(service_fn(|_: Request<Body>| async {
.post_service(service_fn(|_: Request| async {
Ok::<_, Infallible>(Response::new(Body::from("one post")))
}))
.on_service(
MethodFilter::PUT,
service_fn(|_: Request<Body>| async {
service_fn(|_: Request| async {
Ok::<_, Infallible>(Response::new(Body::from("one put")))
}),
),
@ -180,7 +170,7 @@ async fn middleware_on_single_route() {
use tower::ServiceBuilder;
use tower_http::{compression::CompressionLayer, trace::TraceLayer};
async fn handle(_: Request<Body>) -> &'static str {
async fn handle(_: Request) -> &'static str {
"Hello, World!"
}
@ -204,7 +194,7 @@ async fn middleware_on_single_route() {
#[crate::test]
async fn service_in_bottom() {
async fn handler(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
async fn handler(_req: Request) -> Result<Response<Body>, Infallible> {
Ok(Response::new(Body::empty()))
}
@ -242,7 +232,7 @@ async fn wrong_method_service() {
struct Svc;
impl<R> Service<R> for Svc {
type Response = Response<Empty<Bytes>>;
type Response = Response;
type Error = Infallible;
type Future = Ready<Result<Self::Response, Self::Error>>;
@ -251,7 +241,7 @@ async fn wrong_method_service() {
}
fn call(&mut self, _req: R) -> Self::Future {
ready(Ok(Response::new(Empty::new())))
ready(Ok(().into_response()))
}
}
@ -278,7 +268,7 @@ async fn wrong_method_service() {
#[crate::test]
async fn multiple_methods_for_one_handler() {
async fn root(_: Request<Body>) -> &'static str {
async fn root(_: Request) -> &'static str {
"Hello, World!"
}

View File

@ -1,5 +1,5 @@
use super::*;
use crate::{body::boxed, extract::Extension};
use crate::extract::Extension;
use std::collections::HashMap;
use tower_http::services::ServeDir;
@ -141,7 +141,7 @@ async fn nested_url_extractor() {
.route("/baz", get(|uri: Uri| async move { uri.to_string() }))
.route(
"/qux",
get(|req: Request<Body>| async move { req.uri().to_string() }),
get(|req: Request| async move { req.uri().to_string() }),
),
),
);
@ -185,8 +185,8 @@ async fn nested_service_sees_stripped_uri() {
"/bar",
Router::new().route_service(
"/baz",
service_fn(|req: Request<Body>| async move {
let body = boxed(Body::from(req.uri().to_string()));
service_fn(|req: Request| async move {
let body = Body::from(req.uri().to_string());
Ok::<_, Infallible>(Response::new(body))
}),
),

View File

@ -4,7 +4,7 @@ use http::{
header::{HeaderName, HeaderValue},
Request, StatusCode,
};
use hyper::{Body, Server};
use hyper::Server;
use std::net::{SocketAddr, TcpListener};
use tower::make::Shared;
use tower_service::Service;
@ -17,7 +17,10 @@ pub(crate) struct TestClient {
impl TestClient {
pub(crate) fn new<S, ResBody>(svc: S) -> Self
where
S: Service<Request<Body>, Response = http::Response<ResBody>> + Clone + Send + 'static,
S: Service<Request<hyper::Body>, Response = http::Response<ResBody>>
+ Clone
+ Send
+ 'static,
ResBody: HttpBody + Send + 'static,
ResBody::Data: Send,
ResBody::Error: Into<BoxError>,

View File

@ -7,8 +7,8 @@
use axum::{
async_trait,
body::{Body, Bytes},
extract::FromRequest,
http::{Request, StatusCode},
extract::{FromRequest, Request},
http::StatusCode,
middleware::{self, Next},
response::{IntoResponse, Response},
routing::post,
@ -41,10 +41,7 @@ async fn main() {
}
// middleware that shows how to consume the request body upfront
async fn print_request_body(
request: Request<Body>,
next: Next<Body>,
) -> Result<impl IntoResponse, Response> {
async fn print_request_body(request: Request, next: Next) -> Result<impl IntoResponse, Response> {
let request = buffer_request_body(request).await?;
Ok(next.run(request).await)
@ -52,7 +49,7 @@ async fn print_request_body(
// the trick is to take the request apart, buffer the body, do what you need to do, then put
// the request back together
async fn buffer_request_body(request: Request<Body>) -> Result<Request<Body>, Response> {
async fn buffer_request_body(request: Request) -> Result<Request, Response> {
let (parts, body) = request.into_parts();
// this wont work if the body is an long running stream
@ -84,7 +81,7 @@ where
{
type Rejection = Response;
async fn from_request(req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
let body = Bytes::from_request(req, state)
.await
.map_err(|err| err.into_response())?;

View File

@ -6,9 +6,7 @@
//! - Complexity: Manually implementing `FromRequest` results on more complex code
use axum::{
async_trait,
body::Body,
extract::{rejection::JsonRejection, FromRequest, MatchedPath},
http::Request,
extract::{rejection::JsonRejection, FromRequest, MatchedPath, Request},
http::StatusCode,
response::IntoResponse,
RequestPartsExt,
@ -30,7 +28,7 @@ where
{
type Rejection = (StatusCode, axum::Json<Value>);
async fn from_request(req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
let (mut parts, body) = req.into_parts();
// We can use other extractors to provide better rejection messages.

View File

@ -13,8 +13,9 @@
//! Example is based on <https://github.com/hyperium/hyper/blob/master/examples/http_proxy.rs>
use axum::{
body::{self, Body},
http::{Method, Request, StatusCode},
body::Body,
extract::Request,
http::{Method, StatusCode},
response::{IntoResponse, Response},
routing::get,
Router,
@ -59,7 +60,7 @@ async fn main() {
.unwrap();
}
async fn proxy(req: Request<Body>) -> Result<Response, hyper::Error> {
async fn proxy(req: Request) -> Result<Response, hyper::Error> {
tracing::trace!(?req);
if let Some(host_addr) = req.uri().authority().map(|auth| auth.to_string()) {
@ -74,7 +75,7 @@ async fn proxy(req: Request<Body>) -> Result<Response, hyper::Error> {
}
});
Ok(Response::new(body::boxed(body::Empty::new())))
Ok(Response::new(Body::empty()))
} else {
tracing::warn!("CONNECT host is not socket addr: {:?}", req.uri());
Ok((

View File

@ -4,7 +4,7 @@
//! cargo run -p example-low-level-rustls
//! ```
use axum::{body::Body, extract::ConnectInfo, http::Request, routing::get, Router};
use axum::{extract::ConnectInfo, extract::Request, routing::get, Router};
use futures_util::future::poll_fn;
use hyper::server::{
accept::Accept,
@ -67,7 +67,7 @@ async fn main() {
let protocol = protocol.clone();
let svc = MakeService::<_, Request<Body>>::make_service(&mut app, &stream);
let svc = MakeService::<_, Request<hyper::Body>>::make_service(&mut app, &stream);
tokio::spawn(async move {
if let Ok(stream) = acceptor.accept(stream).await {

View File

@ -8,9 +8,8 @@
use axum::{
async_trait,
body::Body,
extract::FromRequest,
http::{header::CONTENT_TYPE, Request, StatusCode},
extract::{FromRequest, Request},
http::{header::CONTENT_TYPE, StatusCode},
response::{IntoResponse, Response},
routing::post,
Form, Json, RequestExt, Router,
@ -61,7 +60,7 @@ where
{
type Rejection = Response;
async fn from_request(req: Request<Body>, _state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, _state: &S) -> Result<Self, Self::Rejection> {
let content_type_header = req.headers().get(CONTENT_TYPE);
let content_type = content_type_header.and_then(|value| value.to_str().ok());

View File

@ -6,7 +6,8 @@
use axum::{
body::{Body, Bytes},
http::{Request, StatusCode},
extract::Request,
http::StatusCode,
middleware::{self, Next},
response::{IntoResponse, Response},
routing::post,
@ -38,8 +39,8 @@ async fn main() {
}
async fn print_request_response(
req: Request<Body>,
next: Next<Body>,
req: Request,
next: Next,
) -> Result<impl IntoResponse, (StatusCode, String)> {
let (parts, body) = req.into_parts();
let bytes = buffer_and_print("request", body).await?;

View File

@ -8,8 +8,7 @@
//! ```
use axum::{
extract::MatchedPath,
http::Request,
extract::{MatchedPath, Request},
middleware::{self, Next},
response::IntoResponse,
routing::get,
@ -94,7 +93,7 @@ fn setup_metrics_recorder() -> PrometheusHandle {
.unwrap()
}
async fn track_metrics<B>(req: Request<B>, next: Next<B>) -> impl IntoResponse {
async fn track_metrics(req: Request, next: Next) -> impl IntoResponse {
let start = Instant::now();
let path = if let Some(matched_path) = req.extensions().get::<MatchedPath>() {
matched_path.as_str().to_owned()

View File

@ -1,6 +1,9 @@
use axum::{body::BoxBody, http::header::CONTENT_TYPE, response::IntoResponse};
use axum::{
extract::Request,
http::header::CONTENT_TYPE,
response::{IntoResponse, Response},
};
use futures::{future::BoxFuture, ready};
use hyper::{Body, Request, Response};
use std::{
convert::Infallible,
task::{Context, Poll},
@ -41,16 +44,16 @@ where
}
}
impl<A, B> Service<Request<Body>> for MultiplexService<A, B>
impl<A, B> Service<Request<hyper::Body>> for MultiplexService<A, B>
where
A: Service<Request<Body>, Error = Infallible>,
A: Service<Request<hyper::Body>, Error = Infallible>,
A::Response: IntoResponse,
A::Future: Send + 'static,
B: Service<Request<Body>>,
B: Service<Request<hyper::Body>>,
B::Response: IntoResponse,
B::Future: Send + 'static,
{
type Response = Response<BoxBody>;
type Response = Response;
type Error = B::Error;
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
@ -73,7 +76,7 @@ where
}
}
fn call(&mut self, req: Request<Body>) -> Self::Future {
fn call(&mut self, req: Request<hyper::Body>) -> Self::Future {
// require users to call `poll_ready` first, if they don't we're allowed to panic
// as per the `tower::Service` contract
assert!(

View File

@ -9,8 +9,8 @@
use axum::{
body::Body,
extract::State,
http::{uri::Uri, Request},
extract::{Request, State},
http::uri::Uri,
response::{IntoResponse, Response},
routing::get,
Router,
@ -36,7 +36,7 @@ async fn main() {
.unwrap();
}
async fn handler(State(client): State<Client>, mut req: Request<Body>) -> Response {
async fn handler(State(client): State<Client>, mut req: Request) -> Response {
let path = req.uri().path();
let path_query = req
.uri()

View File

@ -5,11 +5,7 @@
//! ```
use axum::{
body::Body,
handler::HandlerWithoutStateExt,
http::{Request, StatusCode},
routing::get,
Router,
extract::Request, handler::HandlerWithoutStateExt, http::StatusCode, routing::get, Router,
};
use std::net::SocketAddr;
use tower::ServiceExt;
@ -97,7 +93,7 @@ fn calling_serve_dir_from_a_handler() -> Router {
// call `ServeDir` yourself from a handler
Router::new().nest_service(
"/foo",
get(|request: Request<Body>| async {
get(|request: Request| async {
let service = ServeDir::new("assets");
let result = service.oneshot(request).await;
result

View File

@ -5,9 +5,9 @@
//! ```
use axum::{
body::{Body, Bytes},
extract::{Multipart, Path},
http::{Request, StatusCode},
body::Bytes,
extract::{Multipart, Path, Request},
http::StatusCode,
response::{Html, Redirect},
routing::{get, post},
BoxError, Router,
@ -52,7 +52,7 @@ async fn main() {
// POST'ing to `/file/foo.txt` will create a file called `foo.txt`.
async fn save_request_body(
Path(file_name): Path<String>,
request: Request<Body>,
request: Request,
) -> Result<(), (StatusCode, String)> {
stream_to_file(&file_name, request.into_body()).await
}

View File

@ -162,7 +162,7 @@ mod tests {
// in multiple request
#[tokio::test]
async fn multiple_request() {
let mut app = app();
let mut app = app().into_service();
let request = Request::builder().uri("/").body(Body::empty()).unwrap();
let response = ServiceExt::<Request<Body>>::ready(&mut app)
@ -190,20 +190,15 @@ mod tests {
// tests.
#[tokio::test]
async fn with_into_make_service_with_connect_info() {
let mut app = app().layer(MockConnectInfo(SocketAddr::from(([0, 0, 0, 0], 3000))));
let mut app = app()
.layer(MockConnectInfo(SocketAddr::from(([0, 0, 0, 0], 3000))))
.into_service();
let request = Request::builder()
.uri("/requires-connect-into")
.body(Body::empty())
.unwrap();
let response = app
.as_service()
.ready()
.await
.unwrap()
.call(request)
.await
.unwrap();
let response = app.ready().await.unwrap().call(request).await.unwrap();
assert_eq!(response.status(), StatusCode::OK);
}
}

View File

@ -12,9 +12,8 @@
use async_trait::async_trait;
use axum::{
body::Body,
extract::{rejection::FormRejection, Form, FromRequest},
http::{Request, StatusCode},
extract::{rejection::FormRejection, Form, FromRequest, Request},
http::StatusCode,
response::{Html, IntoResponse, Response},
routing::get,
Router,
@ -70,7 +69,7 @@ where
{
type Rejection = ServerError;
async fn from_request(req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
let Form(value) = Form::<T>::from_request(req, state).await?;
value.validate()?;
Ok(ValidatedForm(value))