Automatically handle http_body::LengthLimitError (#1048)

* Automatically handle `http_body::LengthLimitError`

* add tower-http dev dep to axum-core

* just make it a link

* Make `FailedToBufferBody` an enum

* Fix tests now that tower-http handles `Content-Length`

* Bring back explanation for `LengthLimitError`

* remove todo we likely can't fix

* improve wording in docs
This commit is contained in:
David Pedersen
2022-06-08 13:47:57 +00:00
committed by GitHub
parent 73b1bafbf8
commit ef750799fa
8 changed files with 105 additions and 8 deletions
+39 -4
View File
@@ -1,6 +1,9 @@
//! Rejection response types.
use crate::response::{IntoResponse, Response};
use crate::{
response::{IntoResponse, Response},
BoxError,
};
use http::StatusCode;
use std::fmt;
@@ -28,12 +31,44 @@ impl fmt::Display for BodyAlreadyExtracted {
impl std::error::Error for BodyAlreadyExtracted {}
composite_rejection! {
/// Rejection type for extractors that buffer the request body. Used if the
/// request body cannot be buffered due to an error.
pub enum FailedToBufferBody {
LengthLimitError,
UnknownBodyError,
}
}
impl FailedToBufferBody {
pub(crate) fn from_err<E>(err: E) -> Self
where
E: Into<BoxError>,
{
match err.into().downcast::<http_body::LengthLimitError>() {
Ok(err) => Self::LengthLimitError(LengthLimitError::from_err(err)),
Err(err) => Self::UnknownBodyError(UnknownBodyError::from_err(err)),
}
}
}
define_rejection! {
#[status = PAYLOAD_TOO_LARGE]
#[body = "Failed to buffer the request body"]
/// Encountered some other error when buffering the body.
///
/// This can _only_ happen when you're using [`tower_http::limit::RequestBodyLimitLayer`] or
/// otherwise wrapping request bodies in [`http_body::Limited`].
///
/// [`tower_http::limit::RequestBodyLimitLayer`]: https://docs.rs/tower-http/0.3/tower_http/limit/struct.RequestBodyLimitLayer.html
pub struct LengthLimitError(Error);
}
define_rejection! {
#[status = BAD_REQUEST]
#[body = "Failed to buffer the request body"]
/// Rejection type for extractors that buffer the request body. Used if the
/// request body cannot be buffered due to an error.
pub struct FailedToBufferBody(Error);
/// Encountered an unknown error when buffering the body.
pub struct UnknownBodyError(Error);
}
define_rejection! {
+1
View File
@@ -10,6 +10,7 @@ macro_rules! define_rejection {
pub struct $name(pub(crate) crate::Error);
impl $name {
#[allow(dead_code)]
pub(crate) fn from_err<E>(err: E) -> Self
where
E: Into<crate::BoxError>,