Skip to main content

hpke_http/
limits.rs

1//! Bounded-input policy for protocol version 1.
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
16const BHTTP_FIXED_ALLOWANCE: usize = 256;
17const BHTTP_PER_HEADER_ALLOWANCE: usize = 16;
18
19/// Per-engine limits. Values can become stricter but never exceed hard limits.
20#[derive(Clone, Copy, Debug, Eq, PartialEq)]
21pub struct Limits {
22    /// Maximum plaintext request or response body size.
23    pub max_body_len: usize,
24    /// Maximum combined header-name and header-value bytes per message.
25    pub max_header_bytes: usize,
26    /// Maximum number of header fields per message.
27    pub max_header_count: usize,
28    /// Maximum combined request authority and path size.
29    pub max_target_len: usize,
30}
31
32impl Default for Limits {
33    fn default() -> Self {
34        Self {
35            max_body_len: 8 * 1024 * 1024,
36            max_header_bytes: 16 * 1024,
37            max_header_count: 64,
38            max_target_len: HARD_MAX_TARGET_LEN,
39        }
40    }
41}
42
43impl Limits {
44    /// Validate limits before an engine accepts credentials or messages.
45    ///
46    /// # Errors
47    ///
48    /// Returns [`Error::InvalidConfiguration`] if a value exceeds its hard
49    /// implementation limit.
50    pub fn validate(self) -> Result<Self, Error> {
51        if self.max_body_len > HARD_MAX_BODY_LEN
52            || self.max_header_bytes > HARD_MAX_HEADER_BYTES
53            || self.max_header_count > HARD_MAX_HEADER_COUNT
54            || self.max_target_len > HARD_MAX_TARGET_LEN
55        {
56            return Err(Error::InvalidConfiguration);
57        }
58        Ok(self)
59    }
60
61    pub(crate) fn max_encoded_message_len(self) -> usize {
62        self.max_body_len
63            .saturating_add(self.max_header_bytes)
64            .saturating_add(self.max_target_len)
65            .saturating_add(
66                self.max_header_count
67                    .saturating_mul(BHTTP_PER_HEADER_ALLOWANCE),
68            )
69            .saturating_add(BHTTP_FIXED_ALLOWANCE)
70    }
71}