Module tower_http::limit
source · limit
only.Expand description
Middleware for limiting request bodies.
This layer will also intercept requests with a Content-Length
header
larger than the allowable limit and return an immediate error response
before reading any of the body.
Note that payload length errors can be used by adversaries in an attempt to smuggle requests. When an incoming stream is dropped due to an over-sized payload, servers should close the connection or resynchronize by optimistically consuming some data in an attempt to reach the end of the current HTTP frame. If the incoming stream cannot be resynchronized, then the connection should be closed. If you’re using hyper this is automatically handled for you.
§Examples
§Limiting based on Content-Length
If a Content-Length
header is present and indicates a payload that is
larger than the acceptable limit, then the underlying service will not
be called and a 413 Payload Too Large
response will be generated.
use bytes::Bytes;
use std::convert::Infallible;
use http::{Request, Response, StatusCode, HeaderValue, header::CONTENT_LENGTH};
use http_body_util::{LengthLimitError};
use tower::{Service, ServiceExt, ServiceBuilder};
use tower_http::{body::Limited, limit::RequestBodyLimitLayer};
use http_body_util::Full;
async fn handle(req: Request<Limited<Full<Bytes>>>) -> Result<Response<Full<Bytes>>, Infallible> {
panic!("This should not be hit")
}
let mut svc = ServiceBuilder::new()
// Limit incoming requests to 4096 bytes.
.layer(RequestBodyLimitLayer::new(4096))
.service_fn(handle);
// Call the service with a header that indicates the body is too large.
let mut request = Request::builder()
.header(CONTENT_LENGTH, HeaderValue::from_static("5000"))
.body(Full::<Bytes>::default())
.unwrap();
// let response = svc.ready().await?.call(request).await?;
let response = svc.call(request).await?;
assert_eq!(response.status(), StatusCode::PAYLOAD_TOO_LARGE);
§Limiting without known Content-Length
If a Content-Length
header is not present, then the body will be read
until the configured limit has been reached. If the payload is larger than
the limit, the http_body_util::Limited
body will return an error. This
error can be inspected to determine if it is a http_body_util::LengthLimitError
and return an appropriate response in such case.
Note that no error will be generated if the body is never read. Similarly, if the body would be to large, but is never consumed beyond the length limit, then no error is generated, and handling of the remaining incoming data stream is left to the server implementation as described above.
async fn handle(req: Request<Limited<Full<Bytes>>>) -> Result<Response<Full<Bytes>>, BoxError> {
let data = match req.into_body().collect().await {
Ok(collected) => collected.to_bytes(),
Err(err) => {
if let Some(_) = err.downcast_ref::<LengthLimitError>() {
let mut resp = Response::new(Full::default());
*resp.status_mut() = StatusCode::PAYLOAD_TOO_LARGE;
return Ok(resp);
} else {
return Err(err);
}
}
};
Ok(Response::new(Full::default()))
}
let mut svc = ServiceBuilder::new()
// Limit incoming requests to 4096 bytes.
.layer(RequestBodyLimitLayer::new(4096))
.service_fn(handle);
// Call the service.
let request = Request::new(Full::<Bytes>::default());
let response = svc.ready().await?.call(request).await?;
assert_eq!(response.status(), StatusCode::OK);
// Call the service with a body that is too large.
let request = Request::new(Full::<Bytes>::from(Bytes::from(vec![0u8; 4097])));
let response = svc.ready().await?.call(request).await?;
assert_eq!(response.status(), StatusCode::PAYLOAD_TOO_LARGE);
§Limiting without Content-Length
If enforcement of body size limits is desired without preemptively
handling requests with a Content-Length
header indicating an over-sized
request, consider using MapRequestBody
to wrap the request body with
http_body_util::Limited
and checking for http_body_util::LengthLimitError
like in the previous example.
Structs§
- Middleware that intercepts requests with body lengths greater than the configured limit and converts them into
413 Payload Too Large
responses. - Layer that applies the
RequestBodyLimit
middleware that intercepts requests with body lengths greater than the configured limit and converts them into413 Payload Too Large
responses. - Response body for
RequestBodyLimit
. - Response future for
RequestBodyLimit
.