Skip to main content

hpke_http/
limits.rs

1//! Bounded-input policy for protocol version 3.
2
3use crate::Error;
4
5/// Absolute body limit accepted by the implementation (64 MiB).
6pub const HARD_MAX_BODY_LEN: usize = 64 * 1024 * 1024;
7/// Absolute combined header-name and header-value limit (64 KiB).
8pub const HARD_MAX_HEADER_BYTES: usize = 64 * 1024;
9/// Absolute number of header fields accepted in one message.
10pub const HARD_MAX_HEADER_COUNT: usize = 256;
11/// Absolute combined authority and path limit (8 KiB).
12pub const HARD_MAX_TARGET_LEN: usize = 8 * 1024;
13/// Absolute public identifier limit accepted by the implementation.
14pub const HARD_MAX_ID_LEN: usize = 255;
15/// Absolute clear request body limit (4 GiB).
16pub const HARD_MAX_REQUEST_BYTES: u64 = 4 * 1024 * 1024 * 1024;
17
18/// Per-engine limits. Set values within the hard limits.
19#[derive(Clone, Copy, Debug, Eq, PartialEq)]
20pub struct Limits {
21    /// Maximum body for complete request helpers, finite replies, and SSE blocks.
22    pub max_body_len: usize,
23    /// Maximum combined header-name and header-value bytes per message.
24    pub max_header_bytes: usize,
25    /// Maximum number of header fields per message.
26    pub max_header_count: usize,
27    /// Maximum combined request authority and path size.
28    pub max_target_len: usize,
29    /// Maximum clear request body across all DATA records.
30    pub max_request_bytes: u64,
31}
32
33impl Default for Limits {
34    fn default() -> Self {
35        Self {
36            max_body_len: 8 * 1024 * 1024,
37            max_header_bytes: 16 * 1024,
38            max_header_count: 64,
39            max_target_len: HARD_MAX_TARGET_LEN,
40            max_request_bytes: 1024 * 1024 * 1024,
41        }
42    }
43}
44
45impl Limits {
46    /// Validate limits before an engine accepts credentials or messages.
47    ///
48    /// # Errors
49    ///
50    /// Returns [`Error::InvalidConfiguration`] if a value exceeds its hard
51    /// implementation limit.
52    pub fn validate(self) -> Result<Self, Error> {
53        if self.max_body_len > HARD_MAX_BODY_LEN
54            || self.max_header_bytes > HARD_MAX_HEADER_BYTES
55            || self.max_header_count > HARD_MAX_HEADER_COUNT
56            || self.max_target_len > HARD_MAX_TARGET_LEN
57            || self.max_request_bytes == 0
58            || self.max_request_bytes > HARD_MAX_REQUEST_BYTES
59        {
60            return Err(Error::InvalidConfiguration);
61        }
62        Ok(self)
63    }
64}