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}