Skip to main content

vibeio_http/h3/
options.rs

1//! Configuration options for the native HTTP/3 connection driver.
2
3use crate::h3::settings::LocalSettings;
4
5/// Configuration options for the HTTP/3 connection handler.
6///
7/// Use the builder-style methods to customise behaviour, then pass the finished
8/// value to [`Http3::new`](super::Http3::new).
9///
10/// # Examples
11///
12/// ```rust,ignore
13/// let options = Http3Options::default()
14///     .handshake_timeout(Some(std::time::Duration::from_secs(10)))
15///     .accept_timeout(Some(std::time::Duration::from_secs(60)));
16/// ```
17pub struct Http3Options {
18    pub(super) local_settings: LocalSettings,
19    pub(super) accept_timeout: Option<std::time::Duration>,
20    pub(super) handshake_timeout: Option<std::time::Duration>,
21    pub(super) send_continue_response: bool,
22    pub(super) send_date_header: bool,
23    pub(super) max_local_error_reset_streams: Option<usize>,
24    pub(super) max_pending_accept_reset_streams: Option<usize>,
25}
26
27impl Http3Options {
28    /// Creates a new `Http3Options` with the following defaults:
29    ///
30    /// | Option | Default |
31    /// |---|---|
32    /// | `accept_timeout` | 30 seconds |
33    /// | `handshake_timeout` | 30 seconds |
34    /// | `send_continue_response` | `true` |
35    /// | `send_date_header` | `true` |
36    /// | `qpack_max_table_capacity` | `0` (RFC 9204 default) |
37    ///     | `qpack_blocked_streams` | `0` (RFC 9204 default) |
38    ///     | `max_field_section_size` | 65,536 |
39    ///     | `enable_connect_protocol` | `false` |
40    ///     | `max_local_error_reset_streams` | `1024` |
41    ///     | `max_pending_accept_reset_streams` | `20` |
42    ///
43    /// The QPACK/limit settings are advertised to the peer in this
44    /// endpoint's SETTINGS frame and bound its codecs: the decoder's
45    /// dynamic-table capacity and blocked-stream budget come from
46    /// `qpack_max_table_capacity` and `qpack_blocked_streams`; the peer's
47    /// encoder is limited by them in turn. `max_field_section_size` bounds
48    /// how large a field section this endpoint will accept.
49    #[inline]
50    pub fn new() -> Self {
51        Self {
52            local_settings: LocalSettings::default(),
53            accept_timeout: Some(std::time::Duration::from_secs(30)),
54            handshake_timeout: Some(std::time::Duration::from_secs(30)),
55            send_continue_response: true,
56            send_date_header: true,
57            max_local_error_reset_streams: Some(1024),
58            max_pending_accept_reset_streams: Some(20),
59        }
60    }
61
62    /// Sets the maximum dynamic-table capacity this endpoint will grant the
63    /// peer's QPACK encoder via `SETTINGS_QPACK_MAX_TABLE_CAPACITY` (RFC
64    /// 9204 Section 5).
65    ///
66    /// This is also the capacity this endpoint's own QPACK decoder uses. It
67    /// must not exceed 2^30 - 1. Defaults to **`0`** (no dynamic table).
68    #[inline]
69    pub fn qpack_max_table_capacity(mut self, capacity: u64) -> Self {
70        self.local_settings.qpack_max_table_capacity = capacity;
71        self
72    }
73
74    /// Sets how many field sections this endpoint will keep blocked while
75    /// waiting for dynamic-table entries via
76    /// `SETTINGS_QPACK_BLOCKED_STREAMS` (RFC 9204 Section 5).
77    ///
78    /// Defaults to **`0`**.
79    #[inline]
80    pub fn qpack_blocked_streams(mut self, max: u64) -> Self {
81        self.local_settings.qpack_blocked_streams = max;
82        self
83    }
84
85    /// Sets the maximum field-section size this endpoint will accept via
86    /// `SETTINGS_MAX_FIELD_SECTION_SIZE` (RFC 9114 Section 7.2.4.1).
87    ///
88    /// Pass `None` for unlimited (the RFC default).
89    #[inline]
90    pub fn max_field_section_size(mut self, max: Option<u64>) -> Self {
91        self.local_settings.max_field_section_size = max;
92        self
93    }
94
95    /// Advertises support for the Extended CONNECT method via
96    /// `SETTINGS_ENABLE_CONNECT_PROTOCOL` (RFC 9114 Section 7.2.4.1).
97    ///
98    /// Defaults to **`false`**.
99    #[inline]
100    pub fn enable_connect_protocol(mut self, enable: bool) -> Self {
101        self.local_settings.enable_connect_protocol = enable;
102        self
103    }
104
105    /// Sets the timeout for waiting on the next accepted HTTP/3 request
106    /// resolver.
107    ///
108    /// If no new request arrives before this duration, the connection is
109    /// gracefully shut down and the handler returns a timeout error.
110    /// Pass `None` to disable this timeout. Defaults to **30 seconds**.
111    #[inline]
112    pub fn accept_timeout(mut self, timeout: Option<std::time::Duration>) -> Self {
113        self.accept_timeout = timeout;
114        self
115    }
116
117    /// Sets the timeout for the initial HTTP/3 connection setup (QUIC
118    /// handshake and stream setup).
119    ///
120    /// If the setup does not complete within this duration, the handler
121    /// returns an I/O timeout error. Pass `None` to disable this timeout.
122    /// Defaults to **30 seconds**.
123    #[inline]
124    pub fn handshake_timeout(mut self, timeout: Option<std::time::Duration>) -> Self {
125        self.handshake_timeout = timeout;
126        self
127    }
128
129    /// Controls whether a `100 Continue` interim response is sent when a
130    /// request contains an `Expect: 100-continue` header.
131    ///
132    /// Defaults to **`true`**.
133    #[inline]
134    pub fn send_continue_response(mut self, send: bool) -> Self {
135        self.send_continue_response = send;
136        self
137    }
138
139    /// Controls whether a `Date` header is automatically added to every
140    /// response.
141    ///
142    /// The value is cached and refreshed at most once per second.
143    /// Defaults to **`true`**.
144    #[inline]
145    pub fn send_date_header(mut self, send: bool) -> Self {
146        self.send_date_header = send;
147        self
148    }
149
150    /// Sets the maximum number of RESET_STREAM frames this endpoint sends
151    /// in response to protocol errors made by the peer across the lifetime
152    /// of the connection (RFC 9114 Section 10.5): a peer that keeps
153    /// sending malformed requests past this limit costs the connection
154    /// rather than the stream, which is then closed with `H3_EXCESSIVE_LOAD`.
155    /// `None` disables the limit. Defaults to `Some(1024)`.
156    #[inline]
157    pub fn max_local_error_reset_streams(mut self, max: Option<usize>) -> Self {
158        self.max_local_error_reset_streams = max;
159        self
160    }
161
162    /// Sets the maximum number of streams the peer opened and then
163    /// terminated (RESET_STREAM or STOP_SENDING) before this endpoint
164    /// accepted them (RFC 9114 Section 10.5): a peer that churns through
165    /// streams without dispatching a single request exceeds this budget,
166    /// and the connection is closed with `H3_EXCESSIVE_LOAD`. `None`
167    /// disables the limit. Defaults to `Some(20)`.
168    #[inline]
169    pub fn max_pending_accept_reset_streams(mut self, max: Option<usize>) -> Self {
170        self.max_pending_accept_reset_streams = max;
171        self
172    }
173}
174
175impl Default for Http3Options {
176    #[inline]
177    fn default() -> Self {
178        Self::new()
179    }
180}