Introduce Response type alias as a shorthand for Response<BoxBody> (#590)

* Introduce `Response` type alias as a shorthand

* Don't re-export `Response` at the crate root
This commit is contained in:
Kai Jewson
2021-12-05 19:16:46 +01:00
committed by GitHub
parent cbb34869d8
commit dfb06e721c
41 changed files with 210 additions and 237 deletions
+2 -3
View File
@@ -1,7 +1,6 @@
use super::{FromRequest, RequestParts}; use super::{FromRequest, RequestParts};
use crate::{body::BoxBody, response::IntoResponse}; use crate::response::{IntoResponse, Response};
use async_trait::async_trait; use async_trait::async_trait;
use http::Response;
use std::convert::Infallible; use std::convert::Infallible;
#[async_trait] #[async_trait]
@@ -27,7 +26,7 @@ macro_rules! impl_from_request {
$( $ty: FromRequest<B> + Send, )* $( $ty: FromRequest<B> + Send, )*
B: Send, B: Send,
{ {
type Rejection = Response<BoxBody>; type Rejection = Response;
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> { async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
$( let $ty = $ty::from_request(req).await.map_err(|err| err.into_response())?; )* $( let $ty = $ty::from_request(req).await.map_err(|err| err.into_response())?; )*
+3 -3
View File
@@ -12,7 +12,7 @@ macro_rules! define_rejection {
#[allow(deprecated)] #[allow(deprecated)]
impl $crate::response::IntoResponse for $name { impl $crate::response::IntoResponse for $name {
fn into_response(self) -> http::Response<$crate::body::BoxBody> { fn into_response(self) -> $crate::response::Response {
let mut res = http::Response::new($crate::body::boxed(http_body::Full::from($body))); let mut res = http::Response::new($crate::body::boxed(http_body::Full::from($body)));
*res.status_mut() = http::StatusCode::$status; *res.status_mut() = http::StatusCode::$status;
res res
@@ -54,7 +54,7 @@ macro_rules! define_rejection {
} }
impl crate::response::IntoResponse for $name { impl crate::response::IntoResponse for $name {
fn into_response(self) -> http::Response<$crate::body::BoxBody> { fn into_response(self) -> $crate::response::Response {
let body = http_body::Full::from(format!(concat!($body, ": {}"), self.0)); let body = http_body::Full::from(format!(concat!($body, ": {}"), self.0));
let body = $crate::body::boxed(body); let body = $crate::body::boxed(body);
let mut res = let mut res =
@@ -97,7 +97,7 @@ macro_rules! composite_rejection {
} }
impl $crate::response::IntoResponse for $name { impl $crate::response::IntoResponse for $name {
fn into_response(self) -> http::Response<$crate::body::BoxBody> { fn into_response(self) -> $crate::response::Response {
match self { match self {
$( $(
Self::$variant(inner) => inner.into_response(), Self::$variant(inner) => inner.into_response(),
+7 -7
View File
@@ -1,9 +1,9 @@
use super::IntoResponse; use super::{IntoResponse, Response};
use crate::body::{boxed, BoxBody}; use crate::body::boxed;
use bytes::Bytes; use bytes::Bytes;
use http::{ use http::{
header::{HeaderMap, HeaderName, HeaderValue}, header::{HeaderMap, HeaderName, HeaderValue},
Response, StatusCode, StatusCode,
}; };
use http_body::{Empty, Full}; use http_body::{Empty, Full};
use std::{convert::TryInto, fmt}; use std::{convert::TryInto, fmt};
@@ -55,7 +55,7 @@ use std::{convert::TryInto, fmt};
pub struct Headers<H>(pub H); pub struct Headers<H>(pub H);
impl<H> Headers<H> { impl<H> Headers<H> {
fn try_into_header_map<K, V>(self) -> Result<HeaderMap, Response<BoxBody>> fn try_into_header_map<K, V>(self) -> Result<HeaderMap, Response>
where where
H: IntoIterator<Item = (K, V)>, H: IntoIterator<Item = (K, V)>,
K: TryInto<HeaderName>, K: TryInto<HeaderName>,
@@ -93,7 +93,7 @@ where
V: TryInto<HeaderValue>, V: TryInto<HeaderValue>,
V::Error: fmt::Display, V::Error: fmt::Display,
{ {
fn into_response(self) -> http::Response<BoxBody> { fn into_response(self) -> Response {
let headers = self.try_into_header_map(); let headers = self.try_into_header_map();
match headers { match headers {
@@ -116,7 +116,7 @@ where
V: TryInto<HeaderValue>, V: TryInto<HeaderValue>,
V::Error: fmt::Display, V::Error: fmt::Display,
{ {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
let headers = match self.0.try_into_header_map() { let headers = match self.0.try_into_header_map() {
Ok(headers) => headers, Ok(headers) => headers,
Err(res) => return res, Err(res) => return res,
@@ -135,7 +135,7 @@ where
V: TryInto<HeaderValue>, V: TryInto<HeaderValue>,
V::Error: fmt::Display, V::Error: fmt::Display,
{ {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
let headers = match self.1.try_into_header_map() { let headers = match self.1.try_into_header_map() {
Ok(headers) => headers, Ok(headers) => headers,
Err(res) => return res, Err(res) => return res,
+36 -32
View File
@@ -11,7 +11,7 @@ use crate::{
use bytes::Bytes; use bytes::Bytes;
use http::{ use http::{
header::{self, HeaderMap, HeaderValue}, header::{self, HeaderMap, HeaderValue},
Response, StatusCode, StatusCode,
}; };
use http_body::{ use http_body::{
combinators::{MapData, MapErr}, combinators::{MapData, MapErr},
@@ -24,6 +24,10 @@ mod headers;
#[doc(inline)] #[doc(inline)]
pub use self::headers::Headers; pub use self::headers::Headers;
/// Type alias for [`http::Response`] whose body type defaults to [`BoxBody`], the most common body
/// type used with Axum.
pub type Response<T = BoxBody> = http::Response<T>;
/// Trait for generating responses. /// Trait for generating responses.
/// ///
/// Types that implement `IntoResponse` can be returned from handlers. /// Types that implement `IntoResponse` can be returned from handlers.
@@ -39,10 +43,10 @@ pub use self::headers::Headers;
/// ```rust /// ```rust
/// use axum::{ /// use axum::{
/// Router, /// Router,
/// body::{self, BoxBody, Bytes}, /// body::{self, Bytes},
/// routing::get, /// routing::get,
/// http::{Response, StatusCode}, /// http::StatusCode,
/// response::IntoResponse, /// response::{IntoResponse, Response},
/// }; /// };
/// ///
/// enum MyError { /// enum MyError {
@@ -51,7 +55,7 @@ pub use self::headers::Headers;
/// } /// }
/// ///
/// impl IntoResponse for MyError { /// impl IntoResponse for MyError {
/// fn into_response(self) -> Response<BoxBody> { /// fn into_response(self) -> Response {
/// let body = match self { /// let body = match self {
/// MyError::SomethingWentWrong => { /// MyError::SomethingWentWrong => {
/// body::boxed(body::Full::from("something went wrong")) /// body::boxed(body::Full::from("something went wrong"))
@@ -84,13 +88,13 @@ pub use self::headers::Headers;
/// ///
/// ```rust /// ```rust
/// use axum::{ /// use axum::{
/// body::{self, BoxBody}, /// body,
/// routing::get, /// routing::get,
/// response::IntoResponse, /// response::{IntoResponse, Response},
/// Router, /// Router,
/// }; /// };
/// use http_body::Body; /// use http_body::Body;
/// use http::{Response, HeaderMap}; /// use http::HeaderMap;
/// use bytes::Bytes; /// use bytes::Bytes;
/// use std::{ /// use std::{
/// convert::Infallible, /// convert::Infallible,
@@ -125,7 +129,7 @@ pub use self::headers::Headers;
/// ///
/// // Now we can implement `IntoResponse` directly for `MyBody` /// // Now we can implement `IntoResponse` directly for `MyBody`
/// impl IntoResponse for MyBody { /// impl IntoResponse for MyBody {
/// fn into_response(self) -> Response<BoxBody> { /// fn into_response(self) -> Response {
/// Response::new(body::boxed(self)) /// Response::new(body::boxed(self))
/// } /// }
/// } /// }
@@ -141,17 +145,17 @@ pub use self::headers::Headers;
/// ``` /// ```
pub trait IntoResponse { pub trait IntoResponse {
/// Create a response. /// Create a response.
fn into_response(self) -> Response<BoxBody>; fn into_response(self) -> Response;
} }
impl IntoResponse for () { impl IntoResponse for () {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
Response::new(boxed(Empty::new())) Response::new(boxed(Empty::new()))
} }
} }
impl IntoResponse for Infallible { impl IntoResponse for Infallible {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
match self {} match self {}
} }
} }
@@ -161,7 +165,7 @@ where
T: IntoResponse, T: IntoResponse,
E: IntoResponse, E: IntoResponse,
{ {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
match self { match self {
Ok(value) => value.into_response(), Ok(value) => value.into_response(),
Err(err) => err.into_response(), Err(err) => err.into_response(),
@@ -174,7 +178,7 @@ where
B: http_body::Body<Data = Bytes> + Send + 'static, B: http_body::Body<Data = Bytes> + Send + 'static,
B::Error: Into<BoxError>, B::Error: Into<BoxError>,
{ {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
self.map(boxed) self.map(boxed)
} }
} }
@@ -182,7 +186,7 @@ where
macro_rules! impl_into_response_for_body { macro_rules! impl_into_response_for_body {
($body:ty) => { ($body:ty) => {
impl IntoResponse for $body { impl IntoResponse for $body {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
Response::new(boxed(self)) Response::new(boxed(self))
} }
} }
@@ -193,7 +197,7 @@ impl_into_response_for_body!(Full<Bytes>);
impl_into_response_for_body!(Empty<Bytes>); impl_into_response_for_body!(Empty<Bytes>);
impl IntoResponse for http::response::Parts { impl IntoResponse for http::response::Parts {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
Response::from_parts(self, boxed(Empty::new())) Response::from_parts(self, boxed(Empty::new()))
} }
} }
@@ -202,7 +206,7 @@ impl<E> IntoResponse for http_body::combinators::BoxBody<Bytes, E>
where where
E: Into<BoxError> + 'static, E: Into<BoxError> + 'static,
{ {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
Response::new(boxed(self)) Response::new(boxed(self))
} }
} }
@@ -211,7 +215,7 @@ impl<E> IntoResponse for http_body::combinators::UnsyncBoxBody<Bytes, E>
where where
E: Into<BoxError> + 'static, E: Into<BoxError> + 'static,
{ {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
Response::new(boxed(self)) Response::new(boxed(self))
} }
} }
@@ -222,7 +226,7 @@ where
F: FnMut(B::Data) -> Bytes + Send + 'static, F: FnMut(B::Data) -> Bytes + Send + 'static,
B::Error: Into<BoxError>, B::Error: Into<BoxError>,
{ {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
Response::new(boxed(self)) Response::new(boxed(self))
} }
} }
@@ -233,27 +237,27 @@ where
F: FnMut(B::Error) -> E + Send + 'static, F: FnMut(B::Error) -> E + Send + 'static,
E: Into<BoxError>, E: Into<BoxError>,
{ {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
Response::new(boxed(self)) Response::new(boxed(self))
} }
} }
impl IntoResponse for &'static str { impl IntoResponse for &'static str {
#[inline] #[inline]
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
Cow::Borrowed(self).into_response() Cow::Borrowed(self).into_response()
} }
} }
impl IntoResponse for String { impl IntoResponse for String {
#[inline] #[inline]
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
Cow::<'static, str>::Owned(self).into_response() Cow::<'static, str>::Owned(self).into_response()
} }
} }
impl IntoResponse for Cow<'static, str> { impl IntoResponse for Cow<'static, str> {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
let mut res = Response::new(boxed(Full::from(self))); let mut res = Response::new(boxed(Full::from(self)));
res.headers_mut().insert( res.headers_mut().insert(
header::CONTENT_TYPE, header::CONTENT_TYPE,
@@ -264,7 +268,7 @@ impl IntoResponse for Cow<'static, str> {
} }
impl IntoResponse for Bytes { impl IntoResponse for Bytes {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
let mut res = Response::new(boxed(Full::from(self))); let mut res = Response::new(boxed(Full::from(self)));
res.headers_mut().insert( res.headers_mut().insert(
header::CONTENT_TYPE, header::CONTENT_TYPE,
@@ -275,7 +279,7 @@ impl IntoResponse for Bytes {
} }
impl IntoResponse for &'static [u8] { impl IntoResponse for &'static [u8] {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
let mut res = Response::new(boxed(Full::from(self))); let mut res = Response::new(boxed(Full::from(self)));
res.headers_mut().insert( res.headers_mut().insert(
header::CONTENT_TYPE, header::CONTENT_TYPE,
@@ -286,7 +290,7 @@ impl IntoResponse for &'static [u8] {
} }
impl IntoResponse for Vec<u8> { impl IntoResponse for Vec<u8> {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
let mut res = Response::new(boxed(Full::from(self))); let mut res = Response::new(boxed(Full::from(self)));
res.headers_mut().insert( res.headers_mut().insert(
header::CONTENT_TYPE, header::CONTENT_TYPE,
@@ -297,7 +301,7 @@ impl IntoResponse for Vec<u8> {
} }
impl IntoResponse for Cow<'static, [u8]> { impl IntoResponse for Cow<'static, [u8]> {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
let mut res = Response::new(boxed(Full::from(self))); let mut res = Response::new(boxed(Full::from(self)));
res.headers_mut().insert( res.headers_mut().insert(
header::CONTENT_TYPE, header::CONTENT_TYPE,
@@ -308,7 +312,7 @@ impl IntoResponse for Cow<'static, [u8]> {
} }
impl IntoResponse for StatusCode { impl IntoResponse for StatusCode {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
Response::builder() Response::builder()
.status(self) .status(self)
.body(boxed(Empty::new())) .body(boxed(Empty::new()))
@@ -320,7 +324,7 @@ impl<T> IntoResponse for (StatusCode, T)
where where
T: IntoResponse, T: IntoResponse,
{ {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
let mut res = self.1.into_response(); let mut res = self.1.into_response();
*res.status_mut() = self.0; *res.status_mut() = self.0;
res res
@@ -331,7 +335,7 @@ impl<T> IntoResponse for (HeaderMap, T)
where where
T: IntoResponse, T: IntoResponse,
{ {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
let mut res = self.1.into_response(); let mut res = self.1.into_response();
res.headers_mut().extend(self.0); res.headers_mut().extend(self.0);
res res
@@ -342,7 +346,7 @@ impl<T> IntoResponse for (StatusCode, HeaderMap, T)
where where
T: IntoResponse, T: IntoResponse,
{ {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
let mut res = self.2.into_response(); let mut res = self.2.into_response();
*res.status_mut() = self.0; *res.status_mut() = self.0;
res.headers_mut().extend(self.1); res.headers_mut().extend(self.1);
@@ -351,7 +355,7 @@ where
} }
impl IntoResponse for HeaderMap { impl IntoResponse for HeaderMap {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
let mut res = Response::new(boxed(Empty::new())); let mut res = Response::new(boxed(Empty::new()));
*res.headers_mut() = self; *res.headers_mut() = self;
res res
+2 -3
View File
@@ -1,7 +1,6 @@
use axum::{ use axum::{
body::BoxBody, body::BoxBody,
http::Response, response::{IntoResponse, Response},
response::IntoResponse,
}; };
use axum_debug::debug_handler; use axum_debug::debug_handler;
@@ -15,7 +14,7 @@ impl A {
} }
impl IntoResponse for A { impl IntoResponse for A {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
todo!() todo!()
} }
} }
+5 -7
View File
@@ -1,12 +1,10 @@
use axum::{ use axum::{
async_trait, async_trait,
body::BoxBody,
extract::{ extract::{
rejection::{ExtensionRejection, ExtensionsAlreadyExtracted}, rejection::{ExtensionRejection, ExtensionsAlreadyExtracted},
Extension, FromRequest, RequestParts, Extension, FromRequest, RequestParts,
}, },
http::Response, response::{IntoResponse, Response},
response::IntoResponse,
}; };
use std::{ use std::{
fmt, fmt,
@@ -31,8 +29,8 @@ use std::{
/// async_trait, /// async_trait,
/// extract::{FromRequest, RequestParts}, /// extract::{FromRequest, RequestParts},
/// body::BoxBody, /// body::BoxBody,
/// response::IntoResponse, /// response::{IntoResponse, Response},
/// http::{StatusCode, Response}, /// http::StatusCode,
/// }; /// };
/// ///
/// #[derive(Clone)] /// #[derive(Clone)]
@@ -58,7 +56,7 @@ use std::{
/// where /// where
/// B: Send, /// B: Send,
/// { /// {
/// type Rejection = Response<BoxBody>; /// type Rejection = Response;
/// ///
/// async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> { /// async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
/// // loading a `CurrentUser` requires first loading the `Session` /// // loading a `CurrentUser` requires first loading the `Session`
@@ -157,7 +155,7 @@ impl<R> IntoResponse for CachedRejection<R>
where where
R: IntoResponse, R: IntoResponse,
{ {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
match self { match self {
Self::ExtensionsAlreadyExtracted(inner) => inner.into_response(), Self::ExtensionsAlreadyExtracted(inner) => inner.into_response(),
Self::Inner(inner) => inner.into_response(), Self::Inner(inner) => inner.into_response(),
+4 -4
View File
@@ -1,7 +1,7 @@
use axum::{ use axum::{
body::{self, BoxBody, Full}, body::{self, Full},
http::{header, HeaderValue, Response, StatusCode}, http::{header, HeaderValue, StatusCode},
response::IntoResponse, response::{IntoResponse, Response},
}; };
use serde::Serialize; use serde::Serialize;
@@ -39,7 +39,7 @@ impl ErasedJson {
} }
impl IntoResponse for ErasedJson { impl IntoResponse for ErasedJson {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
let bytes = match self.0 { let bytes = match self.0 {
Ok(res) => res, Ok(res) => res,
Err(err) => { Err(err) => {
+6 -14
View File
@@ -1,8 +1,9 @@
use super::HasRoutes; use super::HasRoutes;
use axum::{ use axum::{
body::{Body, BoxBody}, body::Body,
handler::Handler, handler::Handler,
http::{Request, Response}, http::Request,
response::Response,
routing::{delete, get, on, post, MethodFilter}, routing::{delete, get, on, post, MethodFilter},
Router, Router,
}; };
@@ -139,10 +140,7 @@ impl<B: Send + 'static> Resource<B> {
/// The routes will be nested at `/{resource_name}/:{resource_name}_id`. /// The routes will be nested at `/{resource_name}/:{resource_name}_id`.
pub fn nest<T>(mut self, svc: T) -> Self pub fn nest<T>(mut self, svc: T) -> Self
where where
T: Service<Request<B>, Response = Response<BoxBody>, Error = Infallible> T: Service<Request<B>, Response = Response, Error = Infallible> + Clone + Send + 'static,
+ Clone
+ Send
+ 'static,
T::Future: Send + 'static, T::Future: Send + 'static,
{ {
let path = self.show_update_destroy_path(); let path = self.show_update_destroy_path();
@@ -155,10 +153,7 @@ impl<B: Send + 'static> Resource<B> {
/// The routes will be nested at `/{resource_name}`. /// The routes will be nested at `/{resource_name}`.
pub fn nest_collection<T>(mut self, svc: T) -> Self pub fn nest_collection<T>(mut self, svc: T) -> Self
where where
T: Service<Request<B>, Response = Response<BoxBody>, Error = Infallible> T: Service<Request<B>, Response = Response, Error = Infallible> + Clone + Send + 'static,
+ Clone
+ Send
+ 'static,
T::Future: Send + 'static, T::Future: Send + 'static,
{ {
let path = self.index_create_path(); let path = self.index_create_path();
@@ -176,10 +171,7 @@ impl<B: Send + 'static> Resource<B> {
fn route<T>(mut self, path: &str, svc: T) -> Self fn route<T>(mut self, path: &str, svc: T) -> Self
where where
T: Service<Request<B>, Response = Response<BoxBody>, Error = Infallible> T: Service<Request<B>, Response = Response, Error = Infallible> + Clone + Send + 'static,
+ Clone
+ Send
+ 'static,
T::Future: Send + 'static, T::Future: Send + 'static,
{ {
self.router = self.router.route(path, svc); self.router = self.router.route(path, svc);
+1 -1
View File
@@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
# Unreleased # Unreleased
- None. - **added:** `axum::response::Response` now exists as a shorthand for writing `Response<BoxBody>`.
# 0.4.0 (02. December, 2021) # 0.4.0 (02. December, 2021)
+4 -4
View File
@@ -1,6 +1,6 @@
use crate::{ use crate::{
body::{self, BoxBody}, body,
response::IntoResponse, response::{IntoResponse, Response},
BoxError, Error, BoxError, Error,
}; };
use bytes::Bytes; use bytes::Bytes;
@@ -8,7 +8,7 @@ use futures_util::{
ready, ready,
stream::{self, TryStream}, stream::{self, TryStream},
}; };
use http::{HeaderMap, Response}; use http::HeaderMap;
use http_body::Body; use http_body::Body;
use pin_project_lite::pin_project; use pin_project_lite::pin_project;
use std::{ use std::{
@@ -81,7 +81,7 @@ where
S::Ok: Into<Bytes>, S::Ok: Into<Bytes>,
S::Error: Into<BoxError>, S::Error: Into<BoxError>,
{ {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
Response::new(body::boxed(self)) Response::new(body::boxed(self))
} }
} }
+2 -2
View File
@@ -24,7 +24,7 @@ async fn handler() -> Result<String, StatusCode> {
While it looks like it might fail with a `StatusCode` this actually isn't an While it looks like it might fail with a `StatusCode` this actually isn't an
"error". If this handler returns `Err(some_status_code)` that will still be "error". If this handler returns `Err(some_status_code)` that will still be
converted into a [`Response<_>`] and sent back to the client. This is done converted into a [`Response`] and sent back to the client. This is done
through `StatusCode`'s [`IntoResponse`] implementation. through `StatusCode`'s [`IntoResponse`] implementation.
It doesn't matter whether you return `Err(StatusCode::NOT_FOUND)` or It doesn't matter whether you return `Err(StatusCode::NOT_FOUND)` or
@@ -171,5 +171,5 @@ async fn handle_timeout_error(
[`tower::Service`]: `tower::Service` [`tower::Service`]: `tower::Service`
[`Infallible`]: std::convert::Infallible [`Infallible`]: std::convert::Infallible
[`Response<_>`]: http::Response [`Response`]: crate::response::Response
[`IntoResponse`]: crate::response::IntoResponse [`IntoResponse`]: crate::response::IntoResponse
+12 -10
View File
@@ -55,11 +55,12 @@ compatible with axum. Some commonly used middleware are:
```rust,no_run ```rust,no_run
use axum::{ use axum::{
body::{Body, BoxBody}, response::Response,
routing::get,
http::{Request, Response},
error_handling::HandleErrorLayer,
Router, Router,
body::{Body, BoxBody},
error_handling::HandleErrorLayer,
http::Request,
routing::get,
}; };
use tower::{ use tower::{
filter::AsyncFilterLayer, filter::AsyncFilterLayer,
@@ -90,7 +91,7 @@ async fn map_request(req: Request<Body>) -> Result<Request<Body>, Infallible> {
Ok(req) Ok(req)
} }
async fn map_response(res: Response<BoxBody>) -> Result<Response<BoxBody>, Infallible> { async fn map_response(res: Response) -> Result<Response, Infallible> {
Ok(res) Ok(res)
} }
@@ -112,10 +113,11 @@ You can also write you own middleware by implementing [`tower::Service`]:
```rust ```rust
use axum::{ use axum::{
body::{Body, BoxBody}, response::Response,
routing::get,
http::{Request, Response},
Router, Router,
body::{Body, BoxBody},
http::Request,
routing::get,
}; };
use futures::future::BoxFuture; use futures::future::BoxFuture;
use tower::{Service, layer::layer_fn}; use tower::{Service, layer::layer_fn};
@@ -128,7 +130,7 @@ struct MyMiddleware<S> {
impl<S> Service<Request<Body>> for MyMiddleware<S> impl<S> Service<Request<Body>> for MyMiddleware<S>
where where
S: Service<Request<Body>, Response = Response<BoxBody>> + Clone + Send + 'static, S: Service<Request<Body>, Response = Response> + Clone + Send + 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
{ {
type Response = S::Response; type Response = S::Response;
@@ -148,7 +150,7 @@ where
let mut inner = std::mem::replace(&mut self.inner, clone); let mut inner = std::mem::replace(&mut self.inner, clone);
Box::pin(async move { Box::pin(async move {
let res: Response<BoxBody> = inner.call(req).await?; let res: Response = inner.call(req).await?;
println!("`MyMiddleware` received the response"); println!("`MyMiddleware` received the response");
+8 -9
View File
@@ -1,10 +1,10 @@
#![doc = include_str!("../docs/error_handling.md")] #![doc = include_str!("../docs/error_handling.md")]
use crate::{ use crate::{
body::{boxed, BoxBody, Bytes, Full, HttpBody}, body::{boxed, Bytes, Full, HttpBody},
extract::{FromRequest, RequestParts}, extract::{FromRequest, RequestParts},
http::{Request, Response, StatusCode}, http::{Request, StatusCode},
response::IntoResponse, response::{IntoResponse, Response},
BoxError, BoxError,
}; };
use std::{ use std::{
@@ -126,7 +126,7 @@ where
ResBody: HttpBody<Data = Bytes> + Send + 'static, ResBody: HttpBody<Data = Bytes> + Send + 'static,
ResBody::Error: Into<BoxError>, ResBody::Error: Into<BoxError>,
{ {
type Response = Response<BoxBody>; type Response = Response;
type Error = Infallible; type Error = Infallible;
type Future = future::HandleErrorFuture; type Future = future::HandleErrorFuture;
@@ -168,7 +168,7 @@ macro_rules! impl_service {
ResBody: HttpBody<Data = Bytes> + Send + 'static, ResBody: HttpBody<Data = Bytes> + Send + 'static,
ResBody::Error: Into<BoxError>, ResBody::Error: Into<BoxError>,
{ {
type Response = Response<BoxBody>; type Response = Response;
type Error = Infallible; type Error = Infallible;
type Future = future::HandleErrorFuture; type Future = future::HandleErrorFuture;
@@ -221,8 +221,7 @@ all_the_tuples!(impl_service);
pub mod future { pub mod future {
//! Future types. //! Future types.
use crate::body::BoxBody; use crate::response::Response;
use http::Response;
use pin_project_lite::pin_project; use pin_project_lite::pin_project;
use std::{ use std::{
convert::Infallible, convert::Infallible,
@@ -235,7 +234,7 @@ pub mod future {
/// Response future for [`HandleError`]. /// Response future for [`HandleError`].
pub struct HandleErrorFuture { pub struct HandleErrorFuture {
#[pin] #[pin]
pub(super) future: Pin<Box<dyn Future<Output = Result<Response<BoxBody>, Infallible>> pub(super) future: Pin<Box<dyn Future<Output = Result<Response, Infallible>>
+ Send + Send
+ 'static + 'static
>>, >>,
@@ -243,7 +242,7 @@ pub mod future {
} }
impl Future for HandleErrorFuture { impl Future for HandleErrorFuture {
type Output = Result<Response<BoxBody>, Infallible>; type Output = Result<Response, Infallible>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
self.project().future.poll(cx) self.project().future.poll(cx)
+7 -4
View File
@@ -3,10 +3,13 @@
//! See [`extractor_middleware`] for more details. //! See [`extractor_middleware`] for more details.
use super::{FromRequest, RequestParts}; use super::{FromRequest, RequestParts};
use crate::{body::BoxBody, response::IntoResponse, BoxError}; use crate::{
response::{IntoResponse, Response},
BoxError,
};
use bytes::Bytes; use bytes::Bytes;
use futures_util::{future::BoxFuture, ready}; use futures_util::{future::BoxFuture, ready};
use http::{Request, Response}; use http::Request;
use pin_project_lite::pin_project; use pin_project_lite::pin_project;
use std::{ use std::{
fmt, fmt,
@@ -170,7 +173,7 @@ where
ResBody: http_body::Body<Data = Bytes> + Send + 'static, ResBody: http_body::Body<Data = Bytes> + Send + 'static,
ResBody::Error: Into<BoxError>, ResBody::Error: Into<BoxError>,
{ {
type Response = Response<BoxBody>; type Response = Response;
type Error = S::Error; type Error = S::Error;
type Future = ResponseFuture<ReqBody, S, E>; type Future = ResponseFuture<ReqBody, S, E>;
@@ -229,7 +232,7 @@ where
ResBody: http_body::Body<Data = Bytes> + Send + 'static, ResBody: http_body::Body<Data = Bytes> + Send + 'static,
ResBody::Error: Into<BoxError>, ResBody::Error: Into<BoxError>,
{ {
type Output = Result<Response<BoxBody>, S::Error>; type Output = Result<Response, S::Error>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
loop { loop {
-1
View File
@@ -1,6 +1,5 @@
#![doc = include_str!("../docs/extract.md")] #![doc = include_str!("../docs/extract.md")]
use crate::response::IntoResponse;
use http::header; use http::header;
use rejection::*; use rejection::*;
+4 -4
View File
@@ -4,9 +4,9 @@
mod de; mod de;
use crate::{ use crate::{
body::{boxed, BoxBody, Full}, body::{boxed, Full},
extract::{rejection::*, FromRequest, RequestParts}, extract::{rejection::*, FromRequest, RequestParts},
response::IntoResponse, response::{IntoResponse, Response},
routing::{InvalidUtf8InPathParam, UrlParams}, routing::{InvalidUtf8InPathParam, UrlParams},
}; };
use async_trait::async_trait; use async_trait::async_trait;
@@ -370,7 +370,7 @@ impl FailedToDeserializePathParams {
} }
impl IntoResponse for FailedToDeserializePathParams { impl IntoResponse for FailedToDeserializePathParams {
fn into_response(self) -> http::Response<BoxBody> { fn into_response(self) -> Response {
let (status, body) = match self.0.kind { let (status, body) = match self.0.kind {
ErrorKind::Message(_) ErrorKind::Message(_)
| ErrorKind::InvalidUtf8InPathParam { .. } | ErrorKind::InvalidUtf8InPathParam { .. }
@@ -385,7 +385,7 @@ impl IntoResponse for FailedToDeserializePathParams {
(StatusCode::INTERNAL_SERVER_ERROR, self.0.kind.to_string()) (StatusCode::INTERNAL_SERVER_ERROR, self.0.kind.to_string())
} }
}; };
let mut res = http::Response::new(boxed(Full::from(body))); let mut res = Response::new(boxed(Full::from(body)));
*res.status_mut() = status; *res.status_mut() = status;
res res
} }
+5 -5
View File
@@ -1,8 +1,8 @@
//! Rejection response types. //! Rejection response types.
use super::IntoResponse;
use crate::{ use crate::{
body::{boxed, BoxBody}, body::boxed,
response::{IntoResponse, Response},
BoxError, Error, BoxError, Error,
}; };
use http_body::Full; use http_body::Full;
@@ -87,8 +87,8 @@ impl FailedToDeserializeQueryString {
} }
impl IntoResponse for FailedToDeserializeQueryString { impl IntoResponse for FailedToDeserializeQueryString {
fn into_response(self) -> http::Response<BoxBody> { fn into_response(self) -> Response {
let mut res = http::Response::new(boxed(Full::from(self.to_string()))); let mut res = Response::new(boxed(Full::from(self.to_string())));
*res.status_mut() = http::StatusCode::BAD_REQUEST; *res.status_mut() = http::StatusCode::BAD_REQUEST;
res res
} }
@@ -204,7 +204,7 @@ impl<T> IntoResponse for ContentLengthLimitRejection<T>
where where
T: IntoResponse, T: IntoResponse,
{ {
fn into_response(self) -> http::Response<BoxBody> { fn into_response(self) -> Response {
match self { match self {
Self::PayloadTooLarge(inner) => inner.into_response(), Self::PayloadTooLarge(inner) => inner.into_response(),
Self::LengthRequired(inner) => inner.into_response(), Self::LengthRequired(inner) => inner.into_response(),
+2 -2
View File
@@ -1,5 +1,5 @@
use super::{FromRequest, RequestParts}; use super::{FromRequest, RequestParts};
use crate::{body::BoxBody, response::IntoResponse}; use crate::response::{IntoResponse, Response};
use async_trait::async_trait; use async_trait::async_trait;
use headers::HeaderMapExt; use headers::HeaderMapExt;
use std::ops::Deref; use std::ops::Deref;
@@ -106,7 +106,7 @@ pub enum TypedHeaderRejectionReason {
} }
impl IntoResponse for TypedHeaderRejection { impl IntoResponse for TypedHeaderRejection {
fn into_response(self) -> http::Response<BoxBody> { fn into_response(self) -> Response {
let mut res = self.to_string().into_response(); let mut res = self.to_string().into_response();
*res.status_mut() = http::StatusCode::BAD_REQUEST; *res.status_mut() = http::StatusCode::BAD_REQUEST;
res res
+4 -4
View File
@@ -66,8 +66,8 @@
use self::rejection::*; use self::rejection::*;
use super::{rejection::*, FromRequest, RequestParts}; use super::{rejection::*, FromRequest, RequestParts};
use crate::{ use crate::{
body::{self, BoxBody}, body,
response::IntoResponse, response::{IntoResponse, Response},
Error, Error,
}; };
use async_trait::async_trait; use async_trait::async_trait;
@@ -78,7 +78,7 @@ use futures_util::{
}; };
use http::{ use http::{
header::{self, HeaderName, HeaderValue}, header::{self, HeaderName, HeaderValue},
Method, Response, StatusCode, Method, StatusCode,
}; };
use hyper::upgrade::{OnUpgrade, Upgraded}; use hyper::upgrade::{OnUpgrade, Upgraded};
use sha1::{Digest, Sha1}; use sha1::{Digest, Sha1};
@@ -296,7 +296,7 @@ where
F: FnOnce(WebSocket) -> Fut + Send + 'static, F: FnOnce(WebSocket) -> Fut + Send + 'static,
Fut: Future + Send + 'static, Fut: Future + Send + 'static,
{ {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
// check requested protocols // check requested protocols
let protocol = self let protocol = self
.extractor .extractor
+3 -4
View File
@@ -1,15 +1,14 @@
//! Handler future types. //! Handler future types.
use crate::body::BoxBody; use crate::response::Response;
use futures_util::future::{BoxFuture, Map}; use futures_util::future::{BoxFuture, Map};
use http::Response;
use std::convert::Infallible; use std::convert::Infallible;
opaque_future! { opaque_future! {
/// The response future for [`IntoService`](super::IntoService). /// The response future for [`IntoService`](super::IntoService).
pub type IntoServiceFuture = pub type IntoServiceFuture =
Map< Map<
BoxFuture<'static, Response<BoxBody>>, BoxFuture<'static, Response>,
fn(Response<BoxBody>) -> Result<Response<BoxBody>, Infallible>, fn(Response) -> Result<Response, Infallible>,
>; >;
} }
+3 -3
View File
@@ -1,6 +1,6 @@
use super::Handler; use super::Handler;
use crate::body::BoxBody; use crate::response::Response;
use http::{Request, Response}; use http::Request;
use std::{ use std::{
convert::Infallible, convert::Infallible,
fmt, fmt,
@@ -58,7 +58,7 @@ where
H: Handler<T, B> + Clone + Send + 'static, H: Handler<T, B> + Clone + Send + 'static,
B: Send + 'static, B: Send + 'static,
{ {
type Response = Response<BoxBody>; type Response = Response;
type Error = Infallible; type Error = Infallible;
type Future = super::future::IntoServiceFuture; type Future = super::future::IntoServiceFuture;
+7 -7
View File
@@ -71,18 +71,18 @@
//! [axum-debug]: https://docs.rs/axum-debug //! [axum-debug]: https://docs.rs/axum-debug
use crate::{ use crate::{
body::{boxed, Body, BoxBody}, body::{boxed, Body},
extract::{ extract::{
connect_info::{Connected, IntoMakeServiceWithConnectInfo}, connect_info::{Connected, IntoMakeServiceWithConnectInfo},
FromRequest, RequestParts, FromRequest, RequestParts,
}, },
response::IntoResponse, response::{IntoResponse, Response},
routing::IntoMakeService, routing::IntoMakeService,
BoxError, BoxError,
}; };
use async_trait::async_trait; use async_trait::async_trait;
use bytes::Bytes; use bytes::Bytes;
use http::{Request, Response}; use http::Request;
use std::{fmt, future::Future, marker::PhantomData}; use std::{fmt, future::Future, marker::PhantomData};
use tower::ServiceExt; use tower::ServiceExt;
use tower_layer::Layer; use tower_layer::Layer;
@@ -115,7 +115,7 @@ pub trait Handler<T, B = Body>: Clone + Send + Sized + 'static {
type Sealed: sealed::HiddenTrait; type Sealed: sealed::HiddenTrait;
/// Call the handler with the given request. /// Call the handler with the given request.
async fn call(self, req: Request<B>) -> Response<BoxBody>; async fn call(self, req: Request<B>) -> Response;
/// Apply a [`tower::Layer`] to the handler. /// Apply a [`tower::Layer`] to the handler.
/// ///
@@ -271,7 +271,7 @@ where
{ {
type Sealed = sealed::Hidden; type Sealed = sealed::Hidden;
async fn call(self, _req: Request<B>) -> Response<BoxBody> { async fn call(self, _req: Request<B>) -> Response {
self().await.into_response() self().await.into_response()
} }
} }
@@ -290,7 +290,7 @@ macro_rules! impl_handler {
{ {
type Sealed = sealed::Hidden; type Sealed = sealed::Hidden;
async fn call(self, req: Request<B>) -> Response<BoxBody> { async fn call(self, req: Request<B>) -> Response {
let mut req = RequestParts::new(req); let mut req = RequestParts::new(req);
$( $(
@@ -349,7 +349,7 @@ where
{ {
type Sealed = sealed::Hidden; type Sealed = sealed::Hidden;
async fn call(self, req: Request<ReqBody>) -> Response<BoxBody> { async fn call(self, req: Request<ReqBody>) -> Response {
match self.svc.oneshot(req).await { match self.svc.oneshot(req).await {
Ok(res) => res.map(boxed), Ok(res) => res.map(boxed),
Err(res) => res.into_response(), Err(res) => res.into_response(),
+3 -4
View File
@@ -1,7 +1,7 @@
use crate::{ use crate::{
body::{self, BoxBody}, body,
extract::{rejection::*, FromRequest, RequestParts}, extract::{rejection::*, FromRequest, RequestParts},
response::IntoResponse, response::{IntoResponse, Response},
BoxError, BoxError,
}; };
use async_trait::async_trait; use async_trait::async_trait;
@@ -10,7 +10,6 @@ use http::{
StatusCode, StatusCode,
}; };
use http_body::Full; use http_body::Full;
use hyper::Response;
use serde::{de::DeserializeOwned, Serialize}; use serde::{de::DeserializeOwned, Serialize};
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
@@ -163,7 +162,7 @@ impl<T> IntoResponse for Json<T>
where where
T: Serialize, T: Serialize,
{ {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
let bytes = match serde_json::to_vec(&self.0) { let bytes = match serde_json::to_vec(&self.0) {
Ok(res) => res, Ok(res) => res,
Err(err) => { Err(err) => {
+3 -3
View File
@@ -59,7 +59,7 @@ macro_rules! define_rejection {
#[allow(deprecated)] #[allow(deprecated)]
impl $crate::response::IntoResponse for $name { impl $crate::response::IntoResponse for $name {
fn into_response(self) -> http::Response<$crate::body::BoxBody> { fn into_response(self) -> $crate::response::Response {
let mut res = http::Response::new($crate::body::boxed(http_body::Full::from($body))); let mut res = http::Response::new($crate::body::boxed(http_body::Full::from($body)));
*res.status_mut() = http::StatusCode::$status; *res.status_mut() = http::StatusCode::$status;
res res
@@ -101,7 +101,7 @@ macro_rules! define_rejection {
} }
impl IntoResponse for $name { impl IntoResponse for $name {
fn into_response(self) -> http::Response<$crate::body::BoxBody> { fn into_response(self) -> $crate::response::Response {
let mut res = let mut res =
http::Response::new($crate::body::boxed(http_body::Full::from(format!(concat!($body, ": {}"), self.0)))); http::Response::new($crate::body::boxed(http_body::Full::from(format!(concat!($body, ": {}"), self.0))));
*res.status_mut() = http::StatusCode::$status; *res.status_mut() = http::StatusCode::$status;
@@ -142,7 +142,7 @@ macro_rules! composite_rejection {
} }
impl $crate::response::IntoResponse for $name { impl $crate::response::IntoResponse for $name {
fn into_response(self) -> http::Response<$crate::body::BoxBody> { fn into_response(self) -> $crate::response::Response {
match self { match self {
$( $(
Self::$variant(inner) => inner.into_response(), Self::$variant(inner) => inner.into_response(),
+5 -5
View File
@@ -1,8 +1,8 @@
#![doc = include_str!("../docs/response.md")] #![doc = include_str!("../docs/response.md")]
use axum_core::body::{boxed, BoxBody}; use axum_core::body::boxed;
use bytes::Bytes; use bytes::Bytes;
use http::{header, HeaderValue, Response}; use http::{header, HeaderValue};
use http_body::Full; use http_body::Full;
mod redirect; mod redirect;
@@ -14,7 +14,7 @@ pub mod sse;
pub use crate::Json; pub use crate::Json;
#[doc(inline)] #[doc(inline)]
pub use axum_core::response::{Headers, IntoResponse}; pub use axum_core::response::{Headers, IntoResponse, Response};
#[doc(inline)] #[doc(inline)]
pub use self::{redirect::Redirect, sse::Sse}; pub use self::{redirect::Redirect, sse::Sse};
@@ -29,7 +29,7 @@ impl<T> IntoResponse for Html<T>
where where
T: Into<Full<Bytes>>, T: Into<Full<Bytes>>,
{ {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
let mut res = Response::new(boxed(self.0.into())); let mut res = Response::new(boxed(self.0.into()));
res.headers_mut().insert( res.headers_mut().insert(
header::CONTENT_TYPE, header::CONTENT_TYPE,
@@ -59,7 +59,7 @@ mod tests {
struct MyResponse; struct MyResponse;
impl IntoResponse for MyResponse { impl IntoResponse for MyResponse {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
let mut resp = Response::new(boxed(Empty::new())); let mut resp = Response::new(boxed(Empty::new()));
resp.headers_mut() resp.headers_mut()
.insert(HeaderName::from_static("a"), HeaderValue::from_static("1")); .insert(HeaderName::from_static("a"), HeaderValue::from_static("1"));
+4 -4
View File
@@ -1,6 +1,6 @@
use super::IntoResponse; use super::{IntoResponse, Response};
use crate::body::{boxed, BoxBody}; use crate::body::boxed;
use http::{header::LOCATION, HeaderValue, Response, StatusCode, Uri}; use http::{header::LOCATION, HeaderValue, StatusCode, Uri};
use http_body::Empty; use http_body::Empty;
use std::convert::TryFrom; use std::convert::TryFrom;
@@ -105,7 +105,7 @@ impl Redirect {
} }
impl IntoResponse for Redirect { impl IntoResponse for Redirect {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
let mut res = Response::new(boxed(Empty::new())); let mut res = Response::new(boxed(Empty::new()));
*res.status_mut() = self.status_code; *res.status_mut() = self.status_code;
res.headers_mut().insert(LOCATION, self.location); res.headers_mut().insert(LOCATION, self.location);
+3 -4
View File
@@ -28,8 +28,8 @@
//! ``` //! ```
use crate::{ use crate::{
body::{self, BoxBody}, body,
response::IntoResponse, response::{IntoResponse, Response},
BoxError, BoxError,
}; };
use bytes::Bytes; use bytes::Bytes;
@@ -37,7 +37,6 @@ use futures_util::{
ready, ready,
stream::{Stream, TryStream}, stream::{Stream, TryStream},
}; };
use http::Response;
use http_body::Body as HttpBody; use http_body::Body as HttpBody;
use pin_project_lite::pin_project; use pin_project_lite::pin_project;
use std::{ use std::{
@@ -98,7 +97,7 @@ where
S: Stream<Item = Result<Event, E>> + Send + 'static, S: Stream<Item = Result<Event, E>> + Send + 'static,
E: Into<BoxError>, E: Into<BoxError>,
{ {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
let body = body::boxed(Body { let body = body::boxed(Body {
event_stream: SyncWrapper::new(self.stream), event_stream: SyncWrapper::new(self.stream),
keep_alive: self.keep_alive.map(KeepAliveStream::new), keep_alive: self.keep_alive.map(KeepAliveStream::new),
+3 -4
View File
@@ -1,8 +1,7 @@
//! Future types. //! Future types.
use crate::body::BoxBody; use crate::response::Response;
use futures_util::future::Either; use futures_util::future::Either;
use http::Response;
use std::{convert::Infallible, future::ready}; use std::{convert::Infallible, future::ready};
pub use super::{into_make_service::IntoMakeServiceFuture, route::RouteFuture}; pub use super::{into_make_service::IntoMakeServiceFuture, route::RouteFuture};
@@ -12,7 +11,7 @@ opaque_future! {
pub type RouterFuture<B> = pub type RouterFuture<B> =
futures_util::future::Either< futures_util::future::Either<
RouteFuture<B, Infallible>, RouteFuture<B, Infallible>,
std::future::Ready<Result<Response<BoxBody>, Infallible>>, std::future::Ready<Result<Response, Infallible>>,
>; >;
} }
@@ -21,7 +20,7 @@ impl<B> RouterFuture<B> {
Self::new(Either::Left(future)) Self::new(Either::Left(future))
} }
pub(super) fn from_response(response: Response<BoxBody>) -> Self { pub(super) fn from_response(response: Response) -> Self {
Self::new(Either::Right(ready(Ok(response)))) Self::new(Either::Right(ready(Ok(response))))
} }
} }
+8 -13
View File
@@ -1,8 +1,9 @@
use crate::{ use crate::{
body::{boxed, Body, BoxBody, Bytes}, body::{boxed, Body, Bytes},
error_handling::{HandleError, HandleErrorLayer}, error_handling::{HandleError, HandleErrorLayer},
handler::Handler, handler::Handler,
http::{Method, Request, Response, StatusCode}, http::{Method, Request, StatusCode},
response::Response,
routing::{Fallback, MethodFilter, Route}, routing::{Fallback, MethodFilter, Route},
BoxError, BoxError,
}; };
@@ -638,10 +639,7 @@ impl<ReqBody, E> MethodRouter<ReqBody, E> {
fn fallback_boxed_response_body<S>(mut self, svc: S) -> Self fn fallback_boxed_response_body<S>(mut self, svc: S) -> Self
where where
S: Service<Request<ReqBody>, Response = Response<BoxBody>, Error = E> S: Service<Request<ReqBody>, Response = Response, Error = E> + Clone + Send + 'static,
+ Clone
+ Send
+ 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
{ {
self.fallback = Fallback::Custom(Route::new(svc)); self.fallback = Fallback::Custom(Route::new(svc));
@@ -799,7 +797,7 @@ impl<ReqBody, E> MethodRouter<ReqBody, E> {
where where
F: Clone + Send + 'static, F: Clone + Send + 'static,
HandleError<Route<ReqBody, E>, F, T>: HandleError<Route<ReqBody, E>, F, T>:
Service<Request<ReqBody>, Response = Response<BoxBody>, Error = Infallible>, Service<Request<ReqBody>, Response = Response, Error = Infallible>,
<HandleError<Route<ReqBody, E>, F, T> as Service<Request<ReqBody>>>::Future: Send, <HandleError<Route<ReqBody, E>, F, T> as Service<Request<ReqBody>>>::Future: Send,
T: 'static, T: 'static,
E: 'static, E: 'static,
@@ -810,10 +808,7 @@ impl<ReqBody, E> MethodRouter<ReqBody, E> {
fn on_service_boxed_response_body<S>(self, filter: MethodFilter, svc: S) -> Self fn on_service_boxed_response_body<S>(self, filter: MethodFilter, svc: S) -> Self
where where
S: Service<Request<ReqBody>, Response = Response<BoxBody>, Error = E> S: Service<Request<ReqBody>, Response = Response, Error = E> + Clone + Send + 'static,
+ Clone
+ Send
+ 'static,
S::Future: Send + 'static, S::Future: Send + 'static,
{ {
// written with a pattern match like this to ensure we update all fields // written with a pattern match like this to ensure we update all fields
@@ -898,7 +893,7 @@ where
use crate::routing::future::RouteFuture; use crate::routing::future::RouteFuture;
impl<B, E> Service<Request<B>> for MethodRouter<B, E> { impl<B, E> Service<Request<B>> for MethodRouter<B, E> {
type Response = Response<BoxBody>; type Response = Response;
type Error = E; type Error = E;
type Future = RouteFuture<B, E>; type Future = RouteFuture<B, E>;
@@ -1070,7 +1065,7 @@ mod tests {
async fn call<S>(method: Method, svc: &mut S) -> (StatusCode, String) async fn call<S>(method: Method, svc: &mut S) -> (StatusCode, String)
where where
S: Service<Request<Body>, Response = Response<BoxBody>, Error = Infallible>, S: Service<Request<Body>, Response = Response, Error = Infallible>,
{ {
let request = Request::builder() let request = Request::builder()
.uri("/") .uri("/")
+7 -15
View File
@@ -2,17 +2,18 @@
use self::{future::RouterFuture, not_found::NotFound}; use self::{future::RouterFuture, not_found::NotFound};
use crate::{ use crate::{
body::{boxed, Body, BoxBody}, body::{boxed, Body},
extract::{ extract::{
connect_info::{Connected, IntoMakeServiceWithConnectInfo}, connect_info::{Connected, IntoMakeServiceWithConnectInfo},
MatchedPath, OriginalUri, MatchedPath, OriginalUri,
}, },
response::Response,
routing::strip_prefix::StripPrefix, routing::strip_prefix::StripPrefix,
util::{try_downcast, ByteStr, PercentDecodedByteStr}, util::{try_downcast, ByteStr, PercentDecodedByteStr},
BoxError, BoxError,
}; };
use bytes::Bytes; use bytes::Bytes;
use http::{Request, Response, StatusCode, Uri}; use http::{Request, StatusCode, Uri};
use std::{ use std::{
borrow::Cow, borrow::Cow,
collections::HashMap, collections::HashMap,
@@ -109,10 +110,7 @@ where
#[doc = include_str!("../docs/routing/route.md")] #[doc = include_str!("../docs/routing/route.md")]
pub fn route<T>(mut self, path: &str, service: T) -> Self pub fn route<T>(mut self, path: &str, service: T) -> Self
where where
T: Service<Request<B>, Response = Response<BoxBody>, Error = Infallible> T: Service<Request<B>, Response = Response, Error = Infallible> + Clone + Send + 'static,
+ Clone
+ Send
+ 'static,
T::Future: Send + 'static, T::Future: Send + 'static,
{ {
if path.is_empty() { if path.is_empty() {
@@ -161,10 +159,7 @@ where
#[doc = include_str!("../docs/routing/nest.md")] #[doc = include_str!("../docs/routing/nest.md")]
pub fn nest<T>(mut self, path: &str, svc: T) -> Self pub fn nest<T>(mut self, path: &str, svc: T) -> Self
where where
T: Service<Request<B>, Response = Response<BoxBody>, Error = Infallible> T: Service<Request<B>, Response = Response, Error = Infallible> + Clone + Send + 'static,
+ Clone
+ Send
+ 'static,
T::Future: Send + 'static, T::Future: Send + 'static,
{ {
if path.is_empty() { if path.is_empty() {
@@ -352,10 +347,7 @@ where
#[doc = include_str!("../docs/routing/fallback.md")] #[doc = include_str!("../docs/routing/fallback.md")]
pub fn fallback<T>(mut self, svc: T) -> Self pub fn fallback<T>(mut self, svc: T) -> Self
where where
T: Service<Request<B>, Response = Response<BoxBody>, Error = Infallible> T: Service<Request<B>, Response = Response, Error = Infallible> + Clone + Send + 'static,
+ Clone
+ Send
+ 'static,
T::Future: Send + 'static, T::Future: Send + 'static,
{ {
self.fallback = Fallback::Custom(Route::new(svc)); self.fallback = Fallback::Custom(Route::new(svc));
@@ -461,7 +453,7 @@ impl<B> Service<Request<B>> for Router<B>
where where
B: Send + 'static, B: Send + 'static,
{ {
type Response = Response<BoxBody>; type Response = Response;
type Error = Infallible; type Error = Infallible;
type Future = RouterFuture<B>; type Future = RouterFuture<B>;
+4 -4
View File
@@ -1,5 +1,5 @@
use crate::body::BoxBody; use crate::response::Response;
use http::{Request, Response, StatusCode}; use http::{Request, StatusCode};
use std::{ use std::{
convert::Infallible, convert::Infallible,
future::ready, future::ready,
@@ -18,9 +18,9 @@ impl<B> Service<Request<B>> for NotFound
where where
B: Send + 'static, B: Send + 'static,
{ {
type Response = Response<BoxBody>; type Response = Response;
type Error = Infallible; type Error = Infallible;
type Future = std::future::Ready<Result<Response<BoxBody>, Self::Error>>; type Future = std::future::Ready<Result<Response, Self::Error>>;
#[inline] #[inline]
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+11 -10
View File
@@ -1,5 +1,8 @@
use crate::body::{boxed, Body, BoxBody}; use crate::{
use http::{Request, Response}; body::{boxed, Body},
response::Response,
};
use http::Request;
use http_body::Empty; use http_body::Empty;
use pin_project_lite::pin_project; use pin_project_lite::pin_project;
use std::{ use std::{
@@ -19,14 +22,12 @@ use tower_service::Service;
/// ///
/// You normally shouldn't need to care about this type. It's used in /// You normally shouldn't need to care about this type. It's used in
/// [`Router::layer`](super::Router::layer). /// [`Router::layer`](super::Router::layer).
pub struct Route<B = Body, E = Infallible>( pub struct Route<B = Body, E = Infallible>(pub(crate) BoxCloneService<Request<B>, Response, E>);
pub(crate) BoxCloneService<Request<B>, Response<BoxBody>, E>,
);
impl<B, E> Route<B, E> { impl<B, E> Route<B, E> {
pub(super) fn new<T>(svc: T) -> Self pub(super) fn new<T>(svc: T) -> Self
where where
T: Service<Request<B>, Response = Response<BoxBody>, Error = E> + Clone + Send + 'static, T: Service<Request<B>, Response = Response, Error = E> + Clone + Send + 'static,
T::Future: Send + 'static, T::Future: Send + 'static,
{ {
Self(BoxCloneService::new(svc)) Self(BoxCloneService::new(svc))
@@ -46,7 +47,7 @@ impl<ReqBody, E> fmt::Debug for Route<ReqBody, E> {
} }
impl<B, E> Service<Request<B>> for Route<B, E> { impl<B, E> Service<Request<B>> for Route<B, E> {
type Response = Response<BoxBody>; type Response = Response;
type Error = E; type Error = E;
type Future = RouteFuture<B, E>; type Future = RouteFuture<B, E>;
@@ -66,7 +67,7 @@ pin_project! {
pub struct RouteFuture<B, E> { pub struct RouteFuture<B, E> {
#[pin] #[pin]
future: Oneshot< future: Oneshot<
BoxCloneService<Request<B>, Response<BoxBody>, E>, BoxCloneService<Request<B>, Response, E>,
Request<B>, Request<B>,
>, >,
strip_body: bool, strip_body: bool,
@@ -75,7 +76,7 @@ pin_project! {
impl<B, E> RouteFuture<B, E> { impl<B, E> RouteFuture<B, E> {
pub(crate) fn new( pub(crate) fn new(
future: Oneshot<BoxCloneService<Request<B>, Response<BoxBody>, E>, Request<B>>, future: Oneshot<BoxCloneService<Request<B>, Response, E>, Request<B>>,
) -> Self { ) -> Self {
RouteFuture { RouteFuture {
future, future,
@@ -90,7 +91,7 @@ impl<B, E> RouteFuture<B, E> {
} }
impl<B, E> Future for RouteFuture<B, E> { impl<B, E> Future for RouteFuture<B, E> {
type Output = Result<Response<BoxBody>, E>; type Output = Result<Response, E>;
#[inline] #[inline]
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
@@ -9,10 +9,9 @@
use axum::{ use axum::{
async_trait, async_trait,
body::BoxBody,
extract::{Extension, Path}, extract::{Extension, Path},
http::{Response, StatusCode}, http::StatusCode,
response::IntoResponse, response::{IntoResponse, Response},
routing::{get, post}, routing::{get, post},
AddExtensionLayer, Json, Router, AddExtensionLayer, Json, Router,
}; };
@@ -92,7 +91,7 @@ impl From<UserRepoError> for AppError {
} }
impl IntoResponse for AppError { impl IntoResponse for AppError {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
let (status, error_message) = match self { let (status, error_message) = match self {
AppError::UserRepo(UserRepoError::NotFound) => { AppError::UserRepo(UserRepoError::NotFound) => {
(StatusCode::NOT_FOUND, "User not found") (StatusCode::NOT_FOUND, "User not found")
+4 -4
View File
@@ -13,9 +13,9 @@
//! Example is based on <https://github.com/hyperium/hyper/blob/master/examples/http_proxy.rs> //! Example is based on <https://github.com/hyperium/hyper/blob/master/examples/http_proxy.rs>
use axum::{ use axum::{
body::{self, Body, BoxBody}, body::{self, Body},
http::{Method, Request, Response, StatusCode}, http::{Method, Request, StatusCode},
response::IntoResponse, response::{IntoResponse, Response},
routing::get, routing::get,
Router, Router,
}; };
@@ -55,7 +55,7 @@ async fn main() {
.unwrap(); .unwrap();
} }
async fn proxy(req: Request<Body>) -> Result<Response<BoxBody>, hyper::Error> { async fn proxy(req: Request<Body>) -> Result<Response, hyper::Error> {
tracing::trace!(?req); tracing::trace!(?req);
if let Some(host_addr) = req.uri().authority().map(|auth| auth.to_string()) { if let Some(host_addr) = req.uri().authority().map(|auth| auth.to_string()) {
+3 -4
View File
@@ -8,10 +8,9 @@
use axum::{ use axum::{
async_trait, async_trait,
body::BoxBody,
extract::{FromRequest, RequestParts, TypedHeader}, extract::{FromRequest, RequestParts, TypedHeader},
http::{Response, StatusCode}, http::StatusCode,
response::IntoResponse, response::{IntoResponse, Response},
routing::{get, post}, routing::{get, post},
Json, Router, Json, Router,
}; };
@@ -141,7 +140,7 @@ where
} }
impl IntoResponse for AuthError { impl IntoResponse for AuthError {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
let (status, error_message) = match self { let (status, error_message) = match self {
AuthError::WrongCredentials => (StatusCode::UNAUTHORIZED, "Wrong credentials"), AuthError::WrongCredentials => (StatusCode::UNAUTHORIZED, "Wrong credentials"),
AuthError::MissingCredentials => (StatusCode::BAD_REQUEST, "Missing credentials"), AuthError::MissingCredentials => (StatusCode::BAD_REQUEST, "Missing credentials"),
+3 -4
View File
@@ -9,10 +9,9 @@
use async_session::{MemoryStore, Session, SessionStore}; use async_session::{MemoryStore, Session, SessionStore};
use axum::{ use axum::{
async_trait, async_trait,
body::BoxBody,
extract::{Extension, FromRequest, Query, RequestParts, TypedHeader}, extract::{Extension, FromRequest, Query, RequestParts, TypedHeader},
http::{header::SET_COOKIE, HeaderMap, Response}, http::{header::SET_COOKIE, HeaderMap},
response::{IntoResponse, Redirect}, response::{IntoResponse, Redirect, Response},
routing::get, routing::get,
AddExtensionLayer, Router, AddExtensionLayer, Router,
}; };
@@ -199,7 +198,7 @@ async fn login_authorized(
struct AuthRedirect; struct AuthRedirect;
impl IntoResponse for AuthRedirect { impl IntoResponse for AuthRedirect {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
Redirect::found("/auth/discord".parse().unwrap()).into_response() Redirect::found("/auth/discord".parse().unwrap()).into_response()
} }
} }
+4 -3
View File
@@ -5,9 +5,10 @@
//! ``` //! ```
use axum::{ use axum::{
body::{Body, BoxBody, Bytes}, body::{Body, Bytes},
error_handling::HandleErrorLayer, error_handling::HandleErrorLayer,
http::{Request, Response, StatusCode}, http::{Request, StatusCode},
response::Response,
routing::post, routing::post,
Router, Router,
}; };
@@ -54,7 +55,7 @@ async fn map_request(req: Request<Body>) -> Result<Request<Body>, BoxError> {
Ok(req) Ok(req)
} }
async fn map_response(res: Response<BoxBody>) -> Result<Response<Body>, BoxError> { async fn map_response(res: Response) -> Result<Response<Body>, BoxError> {
let (parts, body) = res.into_parts(); let (parts, body) = res.into_parts();
let bytes = buffer_and_print("response", body).await?; let bytes = buffer_and_print("response", body).await?;
let res = Response::from_parts(parts, Body::from(bytes)); let res = Response::from_parts(parts, Body::from(bytes));
+4 -4
View File
@@ -6,10 +6,10 @@
use askama::Template; use askama::Template;
use axum::{ use axum::{
body::{self, BoxBody, Full}, body::{self, Full},
extract, extract,
http::{Response, StatusCode}, http::StatusCode,
response::{Html, IntoResponse}, response::{Html, IntoResponse, Response},
routing::get, routing::get,
Router, Router,
}; };
@@ -52,7 +52,7 @@ impl<T> IntoResponse for HtmlTemplate<T>
where where
T: Template, T: Template,
{ {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
match self.0.render() { match self.0.render() {
Ok(html) => Html(html).into_response(), Ok(html) => Html(html).into_response(),
Err(err) => Response::builder() Err(err) => Response::builder()
+5 -7
View File
@@ -6,8 +6,8 @@
use axum::{ use axum::{
body::Bytes, body::Bytes,
http::{HeaderMap, Request, Response}, http::{HeaderMap, Request},
response::Html, response::{Html, Response},
routing::get, routing::get,
Router, Router,
}; };
@@ -42,11 +42,9 @@ async fn main() {
.on_request(|_request: &Request<_>, _span: &Span| { .on_request(|_request: &Request<_>, _span: &Span| {
// ... // ...
}) })
.on_response( .on_response(|_response: &Response, _latency: Duration, _span: &Span| {
|_response: &Response<_>, _latency: Duration, _span: &Span| { // ...
// ... })
},
)
.on_body_chunk(|_chunk: &Bytes, _latency: Duration, _span: &Span| { .on_body_chunk(|_chunk: &Bytes, _latency: Duration, _span: &Span| {
// .. // ..
}) })
+3 -4
View File
@@ -12,10 +12,9 @@
use async_trait::async_trait; use async_trait::async_trait;
use axum::{ use axum::{
body::BoxBody,
extract::{Form, FromRequest, RequestParts}, extract::{Form, FromRequest, RequestParts},
http::{Response, StatusCode}, http::StatusCode,
response::{Html, IntoResponse}, response::{Html, IntoResponse, Response},
routing::get, routing::get,
BoxError, Router, BoxError, Router,
}; };
@@ -84,7 +83,7 @@ pub enum ServerError {
} }
impl IntoResponse for ServerError { impl IntoResponse for ServerError {
fn into_response(self) -> Response<BoxBody> { fn into_response(self) -> Response {
match self { match self {
ServerError::ValidationError(_) => { ServerError::ValidationError(_) => {
let message = format!("Input validation error: [{}]", self).replace("\n", ", "); let message = format!("Input validation error: [{}]", self).replace("\n", ", ");
+3 -4
View File
@@ -6,10 +6,9 @@
use axum::{ use axum::{
async_trait, async_trait,
body::BoxBody,
extract::{FromRequest, Path, RequestParts}, extract::{FromRequest, Path, RequestParts},
http::{Response, StatusCode}, http::StatusCode,
response::IntoResponse, response::{IntoResponse, Response},
routing::get, routing::get,
Router, Router,
}; };
@@ -51,7 +50,7 @@ impl<B> FromRequest<B> for Version
where where
B: Send, B: Send,
{ {
type Rejection = Response<BoxBody>; type Rejection = Response;
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> { async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
let params = Path::<HashMap<String, String>>::from_request(req) let params = Path::<HashMap<String, String>>::from_request(req)