-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Limit size of request bodies in
Bytes
extractor (#1362)
* Limit size of request bodies in `Bytes` extractor (#1346) * Apply default limit to request body size * Support disabling the default limit * docs * changelog * fix doc test * fix docs links * Avoid unhelpful compiler suggestion (#1251) Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
- Loading branch information
1 parent
3990c3a
commit 95e21c1
Showing
12 changed files
with
245 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
use self::private::DefaultBodyLimitService; | ||
use tower_layer::Layer; | ||
|
||
/// Layer for configuring the default request body limit. | ||
/// | ||
/// For security reasons, [`Bytes`] will, by default, not accept bodies larger than 2MB. This also | ||
/// applies to extractors that uses [`Bytes`] internally such as `String`, [`Json`], and [`Form`]. | ||
/// | ||
/// This middleware provides ways to configure that. | ||
/// | ||
/// Note that if an extractor consumes the body directly with [`Body::data`], or similar, the | ||
/// default limit is _not_ applied. | ||
/// | ||
/// [`Body::data`]: http_body::Body::data | ||
/// [`Bytes`]: bytes::Bytes | ||
/// [`Json`]: https://docs.rs/axum/0.5/axum/struct.Json.html | ||
/// [`Form`]: https://docs.rs/axum/0.5/axum/struct.Form.html | ||
#[derive(Debug, Clone)] | ||
#[non_exhaustive] | ||
pub struct DefaultBodyLimit; | ||
|
||
impl DefaultBodyLimit { | ||
/// Disable the default request body limit. | ||
/// | ||
/// This must be used to receive bodies larger than the default limit of 2MB using [`Bytes`] or | ||
/// an extractor built on it such as `String`, [`Json`], [`Form`]. | ||
/// | ||
/// Note that if you're accepting data from untrusted remotes it is recommend to add your own | ||
/// limit such as [`tower_http::limit`]. | ||
/// | ||
/// # Example | ||
/// | ||
/// ``` | ||
/// use axum::{ | ||
/// Router, | ||
/// routing::get, | ||
/// body::{Bytes, Body}, | ||
/// extract::DefaultBodyLimit, | ||
/// }; | ||
/// use tower_http::limit::RequestBodyLimitLayer; | ||
/// use http_body::Limited; | ||
/// | ||
/// let app: Router<Limited<Body>> = Router::new() | ||
/// .route("/", get(|body: Bytes| async {})) | ||
/// // Disable the default limit | ||
/// .layer(DefaultBodyLimit::disable()) | ||
/// // Set a different limit | ||
/// .layer(RequestBodyLimitLayer::new(10 * 1000 * 1000)); | ||
/// ``` | ||
/// | ||
/// [`tower_http::limit`]: https://docs.rs/tower-http/0.3.4/tower_http/limit/index.html | ||
/// [`Bytes`]: bytes::Bytes | ||
/// [`Json`]: https://docs.rs/axum/0.5/axum/struct.Json.html | ||
/// [`Form`]: https://docs.rs/axum/0.5/axum/struct.Form.html | ||
pub fn disable() -> Self { | ||
Self | ||
} | ||
} | ||
|
||
impl<S> Layer<S> for DefaultBodyLimit { | ||
type Service = DefaultBodyLimitService<S>; | ||
|
||
fn layer(&self, inner: S) -> Self::Service { | ||
DefaultBodyLimitService { inner } | ||
} | ||
} | ||
|
||
#[derive(Copy, Clone, Debug)] | ||
pub(crate) struct DefaultBodyLimitDisabled; | ||
|
||
mod private { | ||
use super::DefaultBodyLimitDisabled; | ||
use http::Request; | ||
use std::task::Context; | ||
use tower_service::Service; | ||
|
||
#[derive(Debug, Clone, Copy)] | ||
pub struct DefaultBodyLimitService<S> { | ||
pub(super) inner: S, | ||
} | ||
|
||
impl<B, S> Service<Request<B>> for DefaultBodyLimitService<S> | ||
where | ||
S: Service<Request<B>>, | ||
{ | ||
type Response = S::Response; | ||
type Error = S::Error; | ||
type Future = S::Future; | ||
|
||
#[inline] | ||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> std::task::Poll<Result<(), Self::Error>> { | ||
self.inner.poll_ready(cx) | ||
} | ||
|
||
#[inline] | ||
fn call(&mut self, mut req: Request<B>) -> Self::Future { | ||
req.extensions_mut().insert(DefaultBodyLimitDisabled); | ||
self.inner.call(req) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
use axum_macros::debug_handler; | ||
|
||
#[debug_handler] | ||
async fn handler<T>() {} | ||
async fn handler<T>(extract: T) {} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,5 @@ | ||
error: `#[axum_macros::debug_handler]` doesn't support generic functions | ||
--> tests/debug_handler/fail/generics.rs:4:17 | ||
| | ||
4 | async fn handler<T>() {} | ||
4 | async fn handler<T>(extract: T) {} | ||
| ^^^ | ||
|
||
error[E0282]: type annotations needed | ||
--> tests/debug_handler/fail/generics.rs:4:10 | ||
| | ||
4 | async fn handler<T>() {} | ||
| ----- ^^^^^^^ cannot infer type for type parameter `T` declared on the function `handler` | ||
| | | ||
| consider giving `future` a type |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.