Skip to main content

sword_layers/body_limit/
layer.rs

1use crate::{ResponseFnMapper, body_limit::BodyLimitConfig};
2
3use axum::{
4    body::Body,
5    response::{IntoResponse, Response},
6};
7use axum_responses::JsonResponse;
8use tower::{
9    ServiceBuilder,
10    layer::util::{Identity, Stack},
11    util::MapResponseLayer,
12};
13use tower_http::limit::RequestBodyLimitLayer;
14
15type BodyLimitLayerType = ServiceBuilder<
16    Stack<MapResponseLayer<ResponseFnMapper>, Stack<RequestBodyLimitLayer, Identity>>,
17>;
18
19/// ### Body Limit Layer
20///
21/// This structs represents the Body Limit Layer which
22/// restricts the size of incoming request bodies.
23///
24/// The layer is in fact a `ServiceBuilder` that applies a body size limit
25/// and maps responses to `sword` standardized responses.
26pub struct BodyLimitLayer;
27
28impl BodyLimitLayer {
29    pub fn new(config: &BodyLimitConfig) -> BodyLimitLayerType {
30        fn map_body_limit_response(r: Response<Body>) -> Response<Body> {
31            if r.status().as_u16() != 413 {
32                return r;
33            }
34
35            JsonResponse::PayloadTooLarge()
36                .message("The request body exceeds the maximum allowed size by the server")
37                .into_response()
38        }
39
40        ServiceBuilder::new()
41            .layer(RequestBodyLimitLayer::new(config.max_size.parsed))
42            .map_response(map_body_limit_response as ResponseFnMapper)
43    }
44}