Skip to main content

vibeio_http/h2/
options.rs

1use std::time::Duration;
2
3use crate::h2::codec::{DEFAULT_INITIAL_WINDOW_SIZE, DEFAULT_MAX_FRAME_SIZE};
4
5/// HTTP/2 server configuration.
6///
7/// Build one with [`Http2Options::default`] and override individual fields
8/// with the builder methods, then hand it to [`Http2::new`](crate::Http2::new).
9///
10/// Unlike the framing/header limits below, the connection window settings
11/// ([`initial_stream_window_size`](Http2Options::initial_stream_window_size)
12/// and [`initial_connection_window_size`](Http2Options::initial_connection_window_size))
13/// are advisory: a client may shrink them with its own `SETTINGS`, and the
14/// server honours the smaller value.
15#[derive(Debug, Clone)]
16pub struct Http2Options {
17    /// Max time to wait for the client's preface before giving up.
18    pub(crate) handshake_timeout: Option<Duration>,
19    /// Send a `100 Continue` response as soon as a request's headers arrive,
20    /// before its body has been fully read.
21    pub(crate) send_continue_response: bool,
22    /// Insert a `Date` header into every response when absent.
23    pub(crate) send_date_header: bool,
24    /// Maximum number of concurrent streams the server allows.
25    pub(crate) max_concurrent_streams: u32,
26    /// Initial per-stream flow-control window the server advertises.
27    pub(crate) initial_stream_window_size: u32,
28    /// Initial connection-level flow-control window the server uses.
29    pub(crate) initial_connection_window_size: u32,
30    /// Largest frame payload the server will send or receive.
31    pub(crate) max_frame_size: u32,
32    /// Largest uncompressed header list the server will accept.
33    pub(crate) max_header_list_size: u32,
34    /// Whether to enable Extended CONNECT
35    pub(crate) enable_connect_protocol: bool,
36    /// Close a connection after this long with no frame from the peer
37    /// (RFC 9113 Section 10.5). `None` disables the idle timeout.
38    pub(crate) idle_timeout: Option<Duration>,
39}
40
41impl Default for Http2Options {
42    #[inline]
43    fn default() -> Self {
44        Http2Options {
45            handshake_timeout: Some(Duration::from_secs(10)),
46            send_continue_response: true,
47            send_date_header: true,
48            max_concurrent_streams: 200,
49            initial_stream_window_size: DEFAULT_INITIAL_WINDOW_SIZE,
50            initial_connection_window_size: DEFAULT_INITIAL_WINDOW_SIZE,
51            max_frame_size: DEFAULT_MAX_FRAME_SIZE as u32,
52            max_header_list_size: 1024 * 16,
53            enable_connect_protocol: false,
54            idle_timeout: None,
55        }
56    }
57}
58
59impl Http2Options {
60    /// Sets the maximum time to wait for a client to send the HTTP/2
61    /// preface before aborting the connection.
62    #[inline]
63    pub fn handshake_timeout(mut self, handshake_timeout: Option<Duration>) -> Self {
64        self.handshake_timeout = handshake_timeout;
65        self
66    }
67
68    /// Sends `100 Continue` responses automatically when a request has a body.
69    ///
70    /// Defaults to `true`.
71    #[inline]
72    pub fn send_continue_response(mut self, send_continue_response: bool) -> Self {
73        self.send_continue_response = send_continue_response;
74        self
75    }
76
77    /// Inserts a `Date` header into responses that lack one.
78    ///
79    /// Defaults to `true`.
80    #[inline]
81    pub fn send_date_header(mut self, send_date_header: bool) -> Self {
82        self.send_date_header = send_date_header;
83        self
84    }
85
86    /// Sets the maximum number of concurrent streams allowed on a connection.
87    ///
88    /// Defaults to `200`.
89    #[inline]
90    pub fn max_concurrent_streams(mut self, max_concurrent_streams: u32) -> Self {
91        self.max_concurrent_streams = max_concurrent_streams;
92        self
93    }
94
95    /// Sets the initial per-stream flow-control window size advertised to the
96    /// client. Defaults to `1_048_576`.
97    #[inline]
98    pub fn initial_stream_window_size(mut self, initial_stream_window_size: u32) -> Self {
99        self.initial_stream_window_size = initial_stream_window_size;
100        self
101    }
102
103    /// Sets the initial connection-level flow-control window size.
104    /// Defaults to `1_048_576`.
105    #[inline]
106    pub fn initial_connection_window_size(mut self, initial_connection_window_size: u32) -> Self {
107        self.initial_connection_window_size = initial_connection_window_size;
108        self
109    }
110
111    /// Sets the maximum frame size the server will send or receive.
112    /// Defaults to the RFC 9113 default (`16_384`); must not exceed
113    /// `2^24 - 1`.
114    #[inline]
115    pub fn max_frame_size(mut self, max_frame_size: u32) -> Self {
116        self.max_frame_size = max_frame_size;
117        self
118    }
119
120    /// Sets the maximum size of an uncompressed header list the server will
121    /// accept. Defaults to `16_384`.
122    #[inline]
123    pub fn max_header_list_size(mut self, max_header_list_size: u32) -> Self {
124        self.max_header_list_size = max_header_list_size;
125        self
126    }
127
128    /// Sets whether to enable the Extended CONNECT protocol, allowing for
129    /// example for tunneling WebSockets over HTTP/2. Defaults to `false`.
130    #[inline]
131    pub fn enable_connect_protocol(mut self, enable: bool) -> Self {
132        self.enable_connect_protocol = enable;
133        self
134    }
135
136    /// Sets the idle timeout: a connection that receives no frame from the
137    /// peer for this long is closed gracefully with a `GOAWAY` (RFC 9113
138    /// Section 10.5). Defaults to `None` (no idle timeout).
139    #[inline]
140    pub fn idle_timeout(mut self, idle_timeout: Option<Duration>) -> Self {
141        self.idle_timeout = idle_timeout;
142        self
143    }
144}