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///
20/// All sizes count bytes. Each value can be zero except `max_request_bytes`,
21/// which must be at least one. Defaults appear in `Default::default`.
22#[derive(Clone, Copy, Debug, Eq, PartialEq)]
23pub struct Limits {
24 /// Maximum body for complete request helpers, finite replies, and SSE blocks.
25 pub max_body_len: usize,
26 /// Maximum combined header-name and header-value bytes per message.
27 pub max_header_bytes: usize,
28 /// Maximum number of header fields per message.
29 pub max_header_count: usize,
30 /// Maximum combined request authority and path size.
31 pub max_target_len: usize,
32 /// Maximum clear request body across all DATA records.
33 pub max_request_bytes: u64,
34}
35
36impl Default for Limits {
37 fn default() -> Self {
38 Self {
39 max_body_len: 8 * 1024 * 1024,
40 max_header_bytes: 16 * 1024,
41 max_header_count: 64,
42 max_target_len: HARD_MAX_TARGET_LEN,
43 max_request_bytes: 1024 * 1024 * 1024,
44 }
45 }
46}
47
48impl Limits {
49 /// Validate limits before an engine accepts credentials or messages.
50 ///
51 /// # Errors
52 ///
53 /// Returns [`Error::InvalidConfiguration`] if a value exceeds its hard
54 /// implementation limit.
55 pub fn validate(self) -> Result<Self, Error> {
56 if self.max_body_len > HARD_MAX_BODY_LEN
57 || self.max_header_bytes > HARD_MAX_HEADER_BYTES
58 || self.max_header_count > HARD_MAX_HEADER_COUNT
59 || self.max_target_len > HARD_MAX_TARGET_LEN
60 || self.max_request_bytes == 0
61 || self.max_request_bytes > HARD_MAX_REQUEST_BYTES
62 {
63 return Err(Error::InvalidConfiguration);
64 }
65 Ok(self)
66 }
67}