mirror of
https://github.com/tokio-rs/axum.git
synced 2026-08-07 00:00:15 +02:00
axum-core: fix nested error downcast (#3858)
This commit is contained in:
@@ -19,17 +19,19 @@ impl FailedToBufferBody {
|
||||
where
|
||||
E: Into<BoxError>,
|
||||
{
|
||||
// two layers of boxes here because `with_limited_body`
|
||||
// wraps the `http_body_util::Limited` in an `axum_core::Body`
|
||||
// which also wraps the error type
|
||||
let box_error = match err.into().downcast::<Error>() {
|
||||
Ok(err) => err.into_inner(),
|
||||
Err(err) => err,
|
||||
};
|
||||
let box_error = match box_error.downcast::<Error>() {
|
||||
Ok(err) => err.into_inner(),
|
||||
Err(err) => err,
|
||||
};
|
||||
// peel any number of `axum_core::Error` wrappers to reach the underlying source error
|
||||
let mut box_error = err.into();
|
||||
loop {
|
||||
match box_error.downcast::<Error>() {
|
||||
Ok(unwrapped) => {
|
||||
box_error = unwrapped.into_inner();
|
||||
}
|
||||
Err(err) => {
|
||||
box_error = err;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
match box_error.downcast::<http_body_util::LengthLimitError>() {
|
||||
Ok(err) => Self::LengthLimitError(LengthLimitError::from_err(err)),
|
||||
Err(err) => Self::UnknownBodyError(UnknownBodyError::from_err(err)),
|
||||
|
||||
@@ -1352,3 +1352,28 @@ async fn middleware_adding_body() {
|
||||
|
||||
assert_eq!(res.text().await, "…");
|
||||
}
|
||||
|
||||
#[crate::test]
|
||||
async fn nested_body_limit_rejection() {
|
||||
use crate::{
|
||||
extract::Request,
|
||||
middleware::{self, Next},
|
||||
response::Response,
|
||||
};
|
||||
use axum_core::RequestExt;
|
||||
|
||||
async fn limit_middleware(req: Request, next: Next) -> Response {
|
||||
let req = req.with_limited_body();
|
||||
next.run(req).await
|
||||
}
|
||||
|
||||
let app = Router::new()
|
||||
.route("/", post(|_: Bytes| async {}))
|
||||
.layer(middleware::from_fn(limit_middleware))
|
||||
.layer(middleware::from_fn(limit_middleware))
|
||||
.layer(DefaultBodyLimit::max(2));
|
||||
|
||||
let client = TestClient::new(app);
|
||||
let res = client.post("/").body("123").await;
|
||||
assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user