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
+3
View File
@@ -7,8 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
# Unreleased
- **added:** Automatically handle `http_body::LengthLimitError` in `FailedToBufferBody` and map
such errors to `413 Payload Too Large` ([#1048])
- **fixed:** Use `impl IntoResponse` less in docs ([#1049])
[#1048]: https://github.com/tokio-rs/axum/pull/1048
[#1049]: https://github.com/tokio-rs/axum/pull/1049
# 0.2.4 (02. May, 2022)
+1 -1
View File
@@ -15,7 +15,7 @@ async-trait = "0.1"
bytes = "1.0"
futures-util = { version = "0.3", default-features = false, features = ["alloc"] }
http = "0.2.7"
http-body = "0.4"
http-body = "0.4.5"
mime = "0.3.16"
[dev-dependencies]
+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>,