From a96c6876c24faff39d292efab76a126677149603 Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Tue, 8 Aug 2023 11:57:55 +0200 Subject: [PATCH] Clearly document applying `DefaultBodyLimit` to individual routes (#2157) --- axum-core/src/extract/default_body_limit.rs | 22 +++++++ axum/src/routing/tests/mod.rs | 69 +++++++++++++++++++++ 2 files changed, 91 insertions(+) diff --git a/axum-core/src/extract/default_body_limit.rs b/axum-core/src/extract/default_body_limit.rs index 7b37f1edab..cad7c677b5 100644 --- a/axum-core/src/extract/default_body_limit.rs +++ b/axum-core/src/extract/default_body_limit.rs @@ -64,6 +64,28 @@ use tower_layer::Layer; /// extractors and want to sure a limit is also applied there then [`RequestBodyLimit`] should be /// used. /// +/// # Different limits for different routes +/// +/// `DefaultBodyLimit` can also be selectively applied to have different limits for different +/// routes: +/// +/// ``` +/// use axum::{ +/// Router, +/// routing::post, +/// body::Body, +/// http::Request, +/// extract::DefaultBodyLimit, +/// }; +/// +/// let app = Router::new() +/// // this route has a different limit +/// .route("/", post(|request: Request<_>| async {}).layer(DefaultBodyLimit::max(1024))) +/// // this route still has the default limit +/// .route("/foo", post(|request: Request<_>| async {})); +/// # let _: Router = app; +/// ``` +/// /// [`Body::data`]: http_body::Body::data /// [`Bytes`]: bytes::Bytes /// [`Json`]: https://docs.rs/axum/0.6.0/axum/struct.Json.html diff --git a/axum/src/routing/tests/mod.rs b/axum/src/routing/tests/mod.rs index f1a459d645..11ad394315 100644 --- a/axum/src/routing/tests/mod.rs +++ b/axum/src/routing/tests/mod.rs @@ -743,6 +743,75 @@ async fn changing_the_default_limit() { assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE); } +#[crate::test] +async fn changing_the_default_limit_differently_on_different_routes() { + let limit1 = 2; + let limit2 = 10; + + let app = Router::new() + .route( + "/limit1", + post(|_: Bytes| async {}).layer(DefaultBodyLimit::max(limit1)), + ) + .route( + "/limit2", + post(|_: Bytes| async {}).layer(DefaultBodyLimit::max(limit2)), + ) + .route("/default", post(|_: Bytes| async {})); + + let client = TestClient::new(app); + + let res = client + .post("/limit1") + .body(reqwest::Body::from("a".repeat(limit1))) + .send() + .await; + assert_eq!(res.status(), StatusCode::OK); + + let res = client + .post("/limit1") + .body(reqwest::Body::from("a".repeat(limit2))) + .send() + .await; + assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE); + + let res = client + .post("/limit2") + .body(reqwest::Body::from("a".repeat(limit1))) + .send() + .await; + assert_eq!(res.status(), StatusCode::OK); + + let res = client + .post("/limit2") + .body(reqwest::Body::from("a".repeat(limit2))) + .send() + .await; + assert_eq!(res.status(), StatusCode::OK); + + let res = client + .post("/limit2") + .body(reqwest::Body::from("a".repeat(limit1 + limit2))) + .send() + .await; + assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE); + + let res = client + .post("/default") + .body(reqwest::Body::from("a".repeat(limit1 + limit2))) + .send() + .await; + assert_eq!(res.status(), StatusCode::OK); + + let res = client + .post("/default") + // `DEFAULT_LIMIT` is 2mb so make a body larger than that + .body(reqwest::Body::from("a".repeat(3_000_000))) + .send() + .await; + assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE); +} + #[crate::test] async fn limited_body_with_streaming_body() { const LIMIT: usize = 3;