|
1 | | -use axum_core::extract::{FromRequest, FromRequestParts}; |
| 1 | +use crate::extract::{DefaultBodyLimitKind, FromRequest, FromRequestParts}; |
2 | 2 | use futures_util::future::BoxFuture; |
3 | 3 | use http::Request; |
| 4 | +use http_body::Limited; |
4 | 5 |
|
5 | 6 | mod sealed { |
6 | 7 | pub trait Sealed<B> {} |
@@ -48,6 +49,16 @@ pub trait RequestExt<B>: sealed::Sealed<B> + Sized { |
48 | 49 | where |
49 | 50 | E: FromRequestParts<S> + 'static, |
50 | 51 | S: Send + Sync; |
| 52 | + |
| 53 | + /// Apply the [default body limit](crate::extract::DefaultBodyLimit). |
| 54 | + /// |
| 55 | + /// If it is disabled, return the request as-is in `Err`. |
| 56 | + fn with_limited_body(self) -> Result<Request<Limited<B>>, Request<B>>; |
| 57 | + |
| 58 | + /// Consumes the request, returning the body wrapped in [`Limited`] if a |
| 59 | + /// [default limit](crate::extract::DefaultBodyLimit) is in place, or not wrapped if the |
| 60 | + /// default limit is disabled. |
| 61 | + fn into_limited_body(self) -> Result<Limited<B>, B>; |
51 | 62 | } |
52 | 63 |
|
53 | 64 | impl<B> RequestExt<B> for Request<B> |
@@ -105,14 +116,36 @@ where |
105 | 116 | result |
106 | 117 | }) |
107 | 118 | } |
| 119 | + |
| 120 | + fn with_limited_body(self) -> Result<Request<Limited<B>>, Request<B>> { |
| 121 | + // update docs in `axum-core/src/extract/default_body_limit.rs` and |
| 122 | + // `axum/src/docs/extract.md` if this changes |
| 123 | + const DEFAULT_LIMIT: usize = 2_097_152; // 2 mb |
| 124 | + |
| 125 | + match self.extensions().get::<DefaultBodyLimitKind>().copied() { |
| 126 | + Some(DefaultBodyLimitKind::Disable) => Err(self), |
| 127 | + Some(DefaultBodyLimitKind::Limit(limit)) => { |
| 128 | + Ok(self.map(|b| http_body::Limited::new(b, limit))) |
| 129 | + } |
| 130 | + None => Ok(self.map(|b| http_body::Limited::new(b, DEFAULT_LIMIT))), |
| 131 | + } |
| 132 | + } |
| 133 | + |
| 134 | + fn into_limited_body(self) -> Result<Limited<B>, B> { |
| 135 | + self.with_limited_body() |
| 136 | + .map(Request::into_body) |
| 137 | + .map_err(Request::into_body) |
| 138 | + } |
108 | 139 | } |
109 | 140 |
|
110 | 141 | #[cfg(test)] |
111 | 142 | mod tests { |
112 | 143 | use super::*; |
113 | | - use crate::{ext_traits::tests::RequiresState, extract::State}; |
| 144 | + use crate::{ |
| 145 | + ext_traits::tests::{RequiresState, State}, |
| 146 | + extract::FromRef, |
| 147 | + }; |
114 | 148 | use async_trait::async_trait; |
115 | | - use axum_core::extract::FromRef; |
116 | 149 | use http::Method; |
117 | 150 | use hyper::Body; |
118 | 151 |
|
|
0 commit comments