1use std::time::Duration;
5
6const DEFAULT_HTTP2_KEEPALIVE_TIMEOUT_SECS: u64 = 20;
7const DEFAULT_TLS_HANDSHAKE_TIMEOUT: Duration = Duration::from_secs(5);
8const DEFAULT_MAX_PENDING_CONNECTIONS: usize = 4096;
9
10#[derive(Debug, Clone)]
11pub struct Config {
12 init_stream_window_size: Option<u32>,
13 init_connection_window_size: Option<u32>,
14 max_concurrent_streams: Option<u32>,
15 pub(crate) tcp_keepalive: Option<Duration>,
16 http2_keepalive_interval: Option<Duration>,
17 http2_keepalive_timeout: Option<Duration>,
18 http2_adaptive_window: Option<bool>,
19 http2_max_pending_accept_reset_streams: Option<usize>,
20 http2_max_header_list_size: Option<u32>,
21 max_frame_size: Option<u32>,
22 pub(crate) accept_http1: bool,
23 enable_connect_protocol: bool,
24 pub(crate) max_connection_age: Option<Duration>,
25 pub(crate) tls_handshake_timeout: Duration,
26 pub(crate) max_pending_connections: usize,
27}
28
29impl Default for Config {
30 fn default() -> Self {
31 Self {
32 init_stream_window_size: None,
33 init_connection_window_size: None,
34 max_concurrent_streams: None,
35 tcp_keepalive: None,
36 http2_keepalive_interval: None,
37 http2_keepalive_timeout: None,
38 http2_adaptive_window: None,
39 http2_max_pending_accept_reset_streams: None,
40 http2_max_header_list_size: None,
41 max_frame_size: None,
42 accept_http1: true,
43 enable_connect_protocol: true,
44 max_connection_age: None,
45 tls_handshake_timeout: DEFAULT_TLS_HANDSHAKE_TIMEOUT,
46 max_pending_connections: DEFAULT_MAX_PENDING_CONNECTIONS,
47 }
48 }
49}
50
51impl Config {
52 pub fn initial_stream_window_size(self, sz: impl Into<Option<u32>>) -> Self {
59 Self {
60 init_stream_window_size: sz.into(),
61 ..self
62 }
63 }
64
65 pub fn initial_connection_window_size(self, sz: impl Into<Option<u32>>) -> Self {
69 Self {
70 init_connection_window_size: sz.into(),
71 ..self
72 }
73 }
74
75 pub fn max_concurrent_streams(self, max: impl Into<Option<u32>>) -> Self {
82 Self {
83 max_concurrent_streams: max.into(),
84 ..self
85 }
86 }
87
88 pub fn max_connection_age(self, max_connection_age: Duration) -> Self {
92 Self {
93 max_connection_age: Some(max_connection_age),
94 ..self
95 }
96 }
97
98 pub fn http2_keepalive_interval(self, http2_keepalive_interval: Option<Duration>) -> Self {
107 Self {
108 http2_keepalive_interval,
109 ..self
110 }
111 }
112
113 pub fn http2_keepalive_timeout(self, http2_keepalive_timeout: Option<Duration>) -> Self {
120 Self {
121 http2_keepalive_timeout,
122 ..self
123 }
124 }
125
126 pub fn http2_adaptive_window(self, enabled: Option<bool>) -> Self {
130 Self {
131 http2_adaptive_window: enabled,
132 ..self
133 }
134 }
135
136 pub fn http2_max_pending_accept_reset_streams(self, max: Option<usize>) -> Self {
142 Self {
143 http2_max_pending_accept_reset_streams: max,
144 ..self
145 }
146 }
147
148 pub fn tcp_keepalive(self, tcp_keepalive: Option<Duration>) -> Self {
156 Self {
157 tcp_keepalive,
158 ..self
159 }
160 }
161
162 pub fn http2_max_header_list_size(self, max: impl Into<Option<u32>>) -> Self {
166 Self {
167 http2_max_header_list_size: max.into(),
168 ..self
169 }
170 }
171
172 pub fn max_frame_size(self, frame_size: impl Into<Option<u32>>) -> Self {
178 Self {
179 max_frame_size: frame_size.into(),
180 ..self
181 }
182 }
183
184 pub fn accept_http1(self, accept_http1: bool) -> Self {
188 Config {
189 accept_http1,
190 ..self
191 }
192 }
193
194 pub fn tls_handshake_timeout(self, timeout: Duration) -> Self {
200 Config {
201 tls_handshake_timeout: timeout,
202 ..self
203 }
204 }
205
206 pub fn max_pending_connections(self, max: usize) -> Self {
213 Config {
214 max_pending_connections: max,
215 ..self
216 }
217 }
218
219 pub(crate) fn connection_builder(
220 &self,
221 ) -> hyper_util::server::conn::auto::Builder<hyper_util::rt::TokioExecutor> {
222 let mut builder =
223 hyper_util::server::conn::auto::Builder::new(hyper_util::rt::TokioExecutor::new());
224
225 if !self.accept_http1 {
226 builder = builder.http2_only();
227 }
228
229 if self.enable_connect_protocol {
230 builder.http2().enable_connect_protocol();
231 }
232
233 let http2_keepalive_timeout = self
234 .http2_keepalive_timeout
235 .unwrap_or_else(|| Duration::new(DEFAULT_HTTP2_KEEPALIVE_TIMEOUT_SECS, 0));
236
237 builder
238 .http2()
239 .timer(hyper_util::rt::TokioTimer::new())
240 .initial_connection_window_size(self.init_connection_window_size)
241 .initial_stream_window_size(self.init_stream_window_size)
242 .max_concurrent_streams(self.max_concurrent_streams)
243 .keep_alive_interval(self.http2_keepalive_interval)
244 .keep_alive_timeout(http2_keepalive_timeout)
245 .adaptive_window(self.http2_adaptive_window.unwrap_or_default())
246 .max_pending_accept_reset_streams(self.http2_max_pending_accept_reset_streams)
247 .max_frame_size(self.max_frame_size);
248
249 if let Some(max_header_list_size) = self.http2_max_header_list_size {
250 builder.http2().max_header_list_size(max_header_list_size);
251 }
252
253 builder
254 }
255}