hyper_server/
http_config.rs

1use hyper::server::conn::Http;
2use std::time::Duration;
3
4/// Represents a configuration for the [`Http`] protocol.
5/// This allows for detailed customization of various HTTP/1 and HTTP/2 settings.
6#[derive(Debug, Clone)]
7pub struct HttpConfig {
8    /// The inner HTTP configuration from the `hyper` crate.
9    pub(crate) inner: Http,
10}
11
12impl Default for HttpConfig {
13    /// Provides a default HTTP configuration.
14    fn default() -> Self {
15        Self::new()
16    }
17}
18
19impl HttpConfig {
20    /// Creates a new `HttpConfig` with default settings.
21    pub fn new() -> HttpConfig {
22        Self { inner: Http::new() }
23    }
24
25    /// Clones the current configuration state and returns it.
26    /// Useful for building configurations dynamically.
27    pub fn build(&mut self) -> Self {
28        self.clone()
29    }
30
31    /// Configures whether to exclusively support HTTP/1.
32    ///
33    /// When enabled, only HTTP/1 requests are processed, and HTTP/2 requests are rejected.
34    ///
35    /// Default is `false`.
36    pub fn http1_only(&mut self, val: bool) -> &mut Self {
37        self.inner.http1_only(val);
38        self
39    }
40
41    /// Specifies if HTTP/1 connections should be allowed to use half-closures.
42    ///
43    /// A half-closure in TCP occurs when one side of the data stream is terminated,
44    /// but the other side remains open. This setting, when `true`, ensures the server
45    /// doesn't immediately close a connection if a client shuts down their sending side
46    /// while waiting for a response.
47    ///
48    /// Default is `false`.
49    pub fn http1_half_close(&mut self, val: bool) -> &mut Self {
50        self.inner.http1_half_close(val);
51        self
52    }
53
54    /// Enables or disables the keep-alive feature for HTTP/1 connections.
55    ///
56    /// Keep-alive allows the connection to be reused for multiple requests and responses.
57    ///
58    /// Default is true.
59    pub fn http1_keep_alive(&mut self, val: bool) -> &mut Self {
60        self.inner.http1_keep_alive(val);
61        self
62    }
63
64    /// Determines if HTTP/1 connections should write headers with title-case naming.
65    ///
66    /// For example, turning this setting `true` would send headers as "Content-Type" instead of "content-type".
67    /// Note that this has no effect on HTTP/2 connections.
68    ///
69    /// Default is false.
70    pub fn http1_title_case_headers(&mut self, enabled: bool) -> &mut Self {
71        self.inner.http1_title_case_headers(enabled);
72        self
73    }
74
75    /// Determines if HTTP/1 connections should preserve the original case of headers.
76    ///
77    /// By default, headers might be normalized. Enabling this will ensure headers retain their original casing.
78    /// This setting doesn't influence HTTP/2.
79    ///
80    /// Default is false.
81    pub fn http1_preserve_header_case(&mut self, enabled: bool) -> &mut Self {
82        self.inner.http1_preserve_header_case(enabled);
83        self
84    }
85
86    /// Configures a timeout for how long the server will wait for client headers.
87    ///
88    /// If the client doesn't send all headers within this duration, the connection is terminated.
89    ///
90    /// Default is None, meaning no timeout.
91    pub fn http1_header_read_timeout(&mut self, val: Duration) -> &mut Self {
92        self.inner.http1_header_read_timeout(val);
93        self
94    }
95
96    /// Specifies whether to use vectored writes for HTTP/1 connections.
97    ///
98    /// Vectored writes can be efficient for multiple non-contiguous data segments.
99    /// However, certain transports (like many TLS implementations) may not handle vectored writes well.
100    /// When disabled, data is flattened into a single buffer before writing.
101    ///
102    /// Default is `auto`, where the best method is determined dynamically.
103    pub fn http1_writev(&mut self, val: bool) -> &mut Self {
104        self.inner.http1_writev(val);
105        self
106    }
107
108    /// Configures the server to exclusively support HTTP/2.
109    ///
110    /// When enabled, only HTTP/2 requests are processed, and HTTP/1 requests are rejected.
111    ///
112    /// Default is false.
113    pub fn http2_only(&mut self, val: bool) -> &mut Self {
114        self.inner.http2_only(val);
115        self
116    }
117
118    /// Sets the [`SETTINGS_INITIAL_WINDOW_SIZE`][spec] option for HTTP2
119    /// stream-level flow control.
120    ///
121    /// Passing `None` will do nothing.
122    ///
123    /// If not set, hyper will use a default.
124    ///
125    /// [spec]: https://http2.github.io/http2-spec/#SETTINGS_INITIAL_WINDOW_SIZE
126    pub fn http2_initial_stream_window_size(&mut self, sz: impl Into<Option<u32>>) -> &mut Self {
127        self.inner.http2_initial_stream_window_size(sz);
128        self
129    }
130
131    /// Sets the max connection-level flow control for HTTP2.
132    ///
133    /// Passing `None` will do nothing.
134    ///
135    /// If not set, hyper will use a default.
136    pub fn http2_initial_connection_window_size(
137        &mut self,
138        sz: impl Into<Option<u32>>,
139    ) -> &mut Self {
140        self.inner.http2_initial_connection_window_size(sz);
141        self
142    }
143
144    /// Sets whether to use an adaptive flow control.
145    ///
146    /// Enabling this will override the limits set in
147    /// `http2_initial_stream_window_size` and
148    /// `http2_initial_connection_window_size`.
149    pub fn http2_adaptive_window(&mut self, enabled: bool) -> &mut Self {
150        self.inner.http2_adaptive_window(enabled);
151        self
152    }
153
154    /// Enables the [extended CONNECT protocol].
155    ///
156    /// [extended CONNECT protocol]: https://datatracker.ietf.org/doc/html/rfc8441#section-4
157    pub fn http2_enable_connect_protocol(&mut self) -> &mut Self {
158        self.inner.http2_enable_connect_protocol();
159        self
160    }
161
162    /// Sets the maximum frame size to use for HTTP2.
163    ///
164    /// Passing `None` will do nothing.
165    ///
166    /// If not set, hyper will use a default.
167    pub fn http2_max_frame_size(&mut self, sz: impl Into<Option<u32>>) -> &mut Self {
168        self.inner.http2_max_frame_size(sz);
169        self
170    }
171
172    /// Sets the [`SETTINGS_MAX_CONCURRENT_STREAMS`][spec] option for HTTP2
173    /// connections.
174    ///
175    /// Default is no limit (`std::u32::MAX`). Passing `None` will do nothing.
176    ///
177    /// [spec]: https://http2.github.io/http2-spec/#SETTINGS_MAX_CONCURRENT_STREAMS
178    pub fn http2_max_concurrent_streams(&mut self, max: impl Into<Option<u32>>) -> &mut Self {
179        self.inner.http2_max_concurrent_streams(max);
180        self
181    }
182
183    /// Sets the max size of received header frames.
184    ///
185    /// Default is currently ~16MB, but may change.
186    pub fn http2_max_header_list_size(&mut self, max: u32) -> &mut Self {
187        self.inner.http2_max_header_list_size(max);
188        self
189    }
190
191    /// Configures the maximum number of pending reset streams allowed before a GOAWAY will be sent.
192    ///
193    /// This will default to the default value set by the [`h2` crate](https://crates.io/crates/h2).
194    /// As of v0.3.17, it is 20.
195    ///
196    /// See <https://github.com/hyperium/hyper/issues/2877> for more information.
197    pub fn http2_max_pending_accept_reset_streams(
198        &mut self,
199        max: impl Into<Option<usize>>,
200    ) -> &mut Self {
201        self.inner.http2_max_pending_accept_reset_streams(max);
202        self
203    }
204
205    /// Set the maximum write buffer size for each HTTP/2 stream.
206    ///
207    /// Default is currently ~400KB, but may change.
208    ///
209    /// # Panics
210    ///
211    /// The value must be no larger than `u32::MAX`.
212    pub fn http2_max_send_buf_size(&mut self, max: usize) -> &mut Self {
213        self.inner.http2_max_send_buf_size(max);
214        self
215    }
216
217    /// Sets an interval for HTTP2 Ping frames should be sent to keep a
218    /// connection alive.
219    ///
220    /// Pass `None` to disable HTTP2 keep-alive.
221    ///
222    /// Default is currently disabled.
223    pub fn http2_keep_alive_interval(
224        &mut self,
225        interval: impl Into<Option<Duration>>,
226    ) -> &mut Self {
227        self.inner.http2_keep_alive_interval(interval);
228        self
229    }
230
231    /// Sets a timeout for receiving an acknowledgement of the keep-alive ping.
232    ///
233    /// If the ping is not acknowledged within the timeout, the connection will
234    /// be closed. Does nothing if `http2_keep_alive_interval` is disabled.
235    ///
236    /// Default is 20 seconds.
237    pub fn http2_keep_alive_timeout(&mut self, timeout: Duration) -> &mut Self {
238        self.inner.http2_keep_alive_timeout(timeout);
239        self
240    }
241
242    /// Set the maximum buffer size for the HTTP/1 connection.
243    ///
244    /// Default is ~400kb.
245    ///
246    /// # Panics
247    ///
248    /// The minimum value allowed is 8192. This method panics if the passed `max` is less than the minimum.
249    pub fn max_buf_size(&mut self, max: usize) -> &mut Self {
250        self.inner.max_buf_size(max);
251        self
252    }
253
254    /// Determines if multiple responses should be buffered and sent together to support pipelined responses.
255    ///
256    /// This can improve throughput in certain situations, but is experimental and might contain issues.
257    ///
258    /// Default is false.
259    pub fn pipeline_flush(&mut self, enabled: bool) -> &mut Self {
260        self.inner.pipeline_flush(enabled);
261        self
262    }
263}