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 pub(crate) tcp_nodelay: bool,
17 http2_keepalive_interval: Option<Duration>,
18 http2_keepalive_timeout: Option<Duration>,
19 http2_adaptive_window: Option<bool>,
20 http2_max_pending_accept_reset_streams: Option<usize>,
21 http2_max_header_list_size: Option<u32>,
22 max_frame_size: Option<u32>,
23 pub(crate) accept_http1: bool,
24 enable_connect_protocol: bool,
25 pub(crate) max_connection_age: Option<Duration>,
26 pub(crate) tls_handshake_timeout: Duration,
27 pub(crate) max_pending_connections: usize,
28}
29
30impl Default for Config {
31 fn default() -> Self {
32 Self {
33 init_stream_window_size: None,
34 init_connection_window_size: None,
35 max_concurrent_streams: None,
36 tcp_keepalive: None,
37 tcp_nodelay: true,
38 http2_keepalive_interval: None,
39 http2_keepalive_timeout: None,
40 http2_adaptive_window: None,
41 http2_max_pending_accept_reset_streams: None,
42 http2_max_header_list_size: None,
43 max_frame_size: None,
44 accept_http1: true,
45 enable_connect_protocol: true,
46 max_connection_age: None,
47 tls_handshake_timeout: DEFAULT_TLS_HANDSHAKE_TIMEOUT,
48 max_pending_connections: DEFAULT_MAX_PENDING_CONNECTIONS,
49 }
50 }
51}
52
53impl Config {
54 pub fn initial_stream_window_size(self, sz: impl Into<Option<u32>>) -> Self {
61 Self {
62 init_stream_window_size: sz.into(),
63 ..self
64 }
65 }
66
67 pub fn initial_connection_window_size(self, sz: impl Into<Option<u32>>) -> Self {
71 Self {
72 init_connection_window_size: sz.into(),
73 ..self
74 }
75 }
76
77 pub fn max_concurrent_streams(self, max: impl Into<Option<u32>>) -> Self {
84 Self {
85 max_concurrent_streams: max.into(),
86 ..self
87 }
88 }
89
90 pub fn max_connection_age(self, max_connection_age: Duration) -> Self {
94 Self {
95 max_connection_age: Some(max_connection_age),
96 ..self
97 }
98 }
99
100 pub fn http2_keepalive_interval(self, http2_keepalive_interval: Option<Duration>) -> Self {
109 Self {
110 http2_keepalive_interval,
111 ..self
112 }
113 }
114
115 pub fn http2_keepalive_timeout(self, http2_keepalive_timeout: Option<Duration>) -> Self {
122 Self {
123 http2_keepalive_timeout,
124 ..self
125 }
126 }
127
128 pub fn http2_adaptive_window(self, enabled: Option<bool>) -> Self {
132 Self {
133 http2_adaptive_window: enabled,
134 ..self
135 }
136 }
137
138 pub fn http2_max_pending_accept_reset_streams(self, max: Option<usize>) -> Self {
144 Self {
145 http2_max_pending_accept_reset_streams: max,
146 ..self
147 }
148 }
149
150 pub fn tcp_keepalive(self, tcp_keepalive: Option<Duration>) -> Self {
158 Self {
159 tcp_keepalive,
160 ..self
161 }
162 }
163
164 pub fn tcp_nodelay(self, enabled: bool) -> Self {
166 Self {
167 tcp_nodelay: enabled,
168 ..self
169 }
170 }
171
172 pub fn http2_max_header_list_size(self, max: impl Into<Option<u32>>) -> Self {
176 Self {
177 http2_max_header_list_size: max.into(),
178 ..self
179 }
180 }
181
182 pub fn max_frame_size(self, frame_size: impl Into<Option<u32>>) -> Self {
188 Self {
189 max_frame_size: frame_size.into(),
190 ..self
191 }
192 }
193
194 pub fn accept_http1(self, accept_http1: bool) -> Self {
198 Config {
199 accept_http1,
200 ..self
201 }
202 }
203
204 pub fn tls_handshake_timeout(self, timeout: Duration) -> Self {
210 Config {
211 tls_handshake_timeout: timeout,
212 ..self
213 }
214 }
215
216 pub fn max_pending_connections(self, max: usize) -> Self {
223 Config {
224 max_pending_connections: max,
225 ..self
226 }
227 }
228
229 pub(crate) fn connection_builder(
230 &self,
231 ) -> hyper_util::server::conn::auto::Builder<hyper_util::rt::TokioExecutor> {
232 let mut builder =
233 hyper_util::server::conn::auto::Builder::new(hyper_util::rt::TokioExecutor::new());
234
235 if !self.accept_http1 {
236 builder = builder.http2_only();
237 }
238
239 if self.enable_connect_protocol {
240 builder.http2().enable_connect_protocol();
241 }
242
243 let http2_keepalive_timeout = self
244 .http2_keepalive_timeout
245 .unwrap_or_else(|| Duration::new(DEFAULT_HTTP2_KEEPALIVE_TIMEOUT_SECS, 0));
246
247 builder
248 .http2()
249 .timer(hyper_util::rt::TokioTimer::new())
250 .initial_connection_window_size(self.init_connection_window_size)
251 .initial_stream_window_size(self.init_stream_window_size)
252 .max_concurrent_streams(self.max_concurrent_streams)
253 .keep_alive_interval(self.http2_keepalive_interval)
254 .keep_alive_timeout(http2_keepalive_timeout)
255 .adaptive_window(self.http2_adaptive_window.unwrap_or_default())
256 .max_pending_accept_reset_streams(self.http2_max_pending_accept_reset_streams)
257 .max_frame_size(self.max_frame_size);
258
259 if let Some(max_header_list_size) = self.http2_max_header_list_size {
260 builder.http2().max_header_list_size(max_header_list_size);
261 }
262
263 builder
264 }
265}