Skip to main content

rama_http_types/body/
limit.rs

1use rama_core::extensions::Extension;
2
3/// Can be used to communicate the desire to limit the size of request/response bodies.
4#[derive(Debug, Clone, Copy, Extension)]
5#[extension(tags(http))]
6pub struct BodyLimit {
7    kind: Option<BodyLimitKind>,
8}
9
10#[derive(Debug, Clone, Copy)]
11enum BodyLimitKind {
12    Bidirectional(usize, usize),
13    Request(usize),
14    Response(usize),
15}
16
17impl BodyLimit {
18    /// Create a new [`BodyLimit`], with the given limit to be applied to the request only.
19    #[must_use]
20    pub fn request_only(limit: usize) -> Self {
21        Self {
22            kind: if limit == 0 {
23                None
24            } else {
25                Some(BodyLimitKind::Request(limit))
26            },
27        }
28    }
29
30    /// Create a new [`BodyLimit`], with the given limit to be applied to the response only.
31    #[must_use]
32    pub fn response_only(limit: usize) -> Self {
33        Self {
34            kind: if limit == 0 {
35                None
36            } else {
37                Some(BodyLimitKind::Response(limit))
38            },
39        }
40    }
41
42    /// Create a new [`BodyLimit`], with the given limit to be applied to both the request and response bodies.
43    #[must_use]
44    pub fn symmetric(limit: usize) -> Self {
45        Self {
46            kind: if limit == 0 {
47                None
48            } else {
49                Some(BodyLimitKind::Bidirectional(limit, limit))
50            },
51        }
52    }
53
54    /// Create a new [`BodyLimit`], with the given limits
55    /// respectively to be applied to the request and response bodies.
56    #[must_use]
57    pub fn asymmetric(request: usize, response: usize) -> Self {
58        match (request, response) {
59            (0, 0) => Self { kind: None },
60            (0, response) => Self {
61                kind: Some(BodyLimitKind::Response(response)),
62            },
63            (request, 0) => Self {
64                kind: Some(BodyLimitKind::Request(request)),
65            },
66            (request, response) => Self {
67                kind: Some(BodyLimitKind::Bidirectional(request, response)),
68            },
69        }
70    }
71
72    /// Get the limit for the request body, if any.
73    #[must_use]
74    pub fn request(&self) -> Option<usize> {
75        match self.kind {
76            Some(BodyLimitKind::Request(limit)) => Some(limit),
77            Some(BodyLimitKind::Bidirectional(request, _)) => Some(request),
78            _ => None,
79        }
80    }
81
82    /// Get the limit for the response body, if any.
83    #[must_use]
84    pub fn response(&self) -> Option<usize> {
85        match self.kind {
86            Some(BodyLimitKind::Response(limit)) => Some(limit),
87            Some(BodyLimitKind::Bidirectional(_, response)) => Some(response),
88            _ => None,
89        }
90    }
91}