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}