Skip to main content

xitca_http/
config.rs

1//! Configuration for http service middlewares.
2
3use core::time::Duration;
4
5/// The default maximum read buffer size. If the head gets this big and
6/// a message is still not complete, a `TooLarge` error is triggered.
7///
8/// When handing request body ff the buffer gets this big a force yield
9/// from Io stream read would happen.
10pub const DEFAULT_READ_BUF_LIMIT: usize = 1024 * 1024;
11
12/// The default maximum write buffer size. If the buffer gets this big and
13/// a message is still not complete, a force draining of Io stream write
14/// would happen.
15pub const DEFAULT_WRITE_BUF_LIMIT: usize = 8192 + 4096 * 100;
16
17/// The default maximum request header fields possible for one request.
18///
19/// 64 chosen for no particular reason.
20pub const DEFAULT_HEADER_LIMIT: usize = 64;
21
22#[derive(Copy, Clone)]
23pub struct HttpServiceConfig<
24    const HEADER_LIMIT: usize = DEFAULT_HEADER_LIMIT,
25    const READ_BUF_LIMIT: usize = DEFAULT_READ_BUF_LIMIT,
26    const WRITE_BUF_LIMIT: usize = DEFAULT_WRITE_BUF_LIMIT,
27> {
28    pub(crate) vectored_write: bool,
29    pub(crate) keep_alive_timeout: Duration,
30    pub(crate) request_head_timeout: Duration,
31    pub(crate) tls_accept_timeout: Duration,
32    pub(crate) peek_protocol: bool,
33    pub(crate) h2_max_concurrent_streams: u32,
34    pub(crate) h2_initial_window_size: u32,
35    pub(crate) h2_max_frame_size: u32,
36    pub(crate) h2_max_header_list_size: u32,
37}
38
39impl Default for HttpServiceConfig {
40    fn default() -> Self {
41        Self::new()
42    }
43}
44
45impl HttpServiceConfig {
46    pub const fn new() -> Self {
47        Self {
48            vectored_write: true,
49            keep_alive_timeout: Duration::from_secs(5),
50            request_head_timeout: Duration::from_secs(5),
51            tls_accept_timeout: Duration::from_secs(3),
52            peek_protocol: false,
53            h2_max_concurrent_streams: 256,
54            h2_initial_window_size: 65_535,
55            h2_max_frame_size: 16_384,
56            h2_max_header_list_size: 16 * 1024 * 1024,
57        }
58    }
59}
60
61impl<const HEADER_LIMIT: usize, const READ_BUF_LIMIT: usize, const WRITE_BUF_LIMIT: usize>
62    HttpServiceConfig<HEADER_LIMIT, READ_BUF_LIMIT, WRITE_BUF_LIMIT>
63{
64    /// Disable vectored write even when IO is able to perform it.
65    ///
66    /// This is beneficial when dealing with small size of response body.
67    pub fn disable_vectored_write(mut self) -> Self {
68        self.vectored_write = false;
69        self
70    }
71
72    /// Define duration of how long an idle connection is kept alive.
73    ///
74    /// connection have not done any IO after duration would be closed. IO operation
75    /// can possibly result in reset of the duration.
76    pub fn keep_alive_timeout(mut self, dur: Duration) -> Self {
77        self.keep_alive_timeout = dur;
78        self
79    }
80
81    /// Define duration of how long a connection must finish it's request head transferring.
82    /// starting from first byte(s) of current request(s) received from peer.
83    ///
84    /// connection can not make a single request after duration would be closed.
85    pub fn request_head_timeout(mut self, dur: Duration) -> Self {
86        self.request_head_timeout = dur;
87        self
88    }
89
90    /// Define duration of how long a connection must finish it's tls handshake.
91    /// (If tls is enabled)
92    ///
93    /// Connection can not finish handshake after duration would be closed.
94    pub fn tls_accept_timeout(mut self, dur: Duration) -> Self {
95        self.tls_accept_timeout = dur;
96        self
97    }
98
99    /// Define max read buffer size for a connection.
100    ///
101    /// See [DEFAULT_READ_BUF_LIMIT] for default value
102    /// and behavior.
103    pub fn max_read_buf_size<const READ_BUF_LIMIT_2: usize>(
104        self,
105    ) -> HttpServiceConfig<HEADER_LIMIT, READ_BUF_LIMIT_2, WRITE_BUF_LIMIT> {
106        self.mutate_const_generic::<HEADER_LIMIT, READ_BUF_LIMIT_2, WRITE_BUF_LIMIT>()
107    }
108
109    /// Define max write buffer size for a connection.
110    ///
111    /// See [DEFAULT_WRITE_BUF_LIMIT] for default value
112    /// and behavior.
113    pub fn max_write_buf_size<const WRITE_BUF_LIMIT_2: usize>(
114        self,
115    ) -> HttpServiceConfig<HEADER_LIMIT, READ_BUF_LIMIT, WRITE_BUF_LIMIT_2> {
116        self.mutate_const_generic::<HEADER_LIMIT, READ_BUF_LIMIT, WRITE_BUF_LIMIT_2>()
117    }
118
119    /// Define max request header count for a connection.    
120    ///
121    /// See [DEFAULT_HEADER_LIMIT] for default value
122    /// and behavior.
123    pub fn max_request_headers<const HEADER_LIMIT_2: usize>(
124        self,
125    ) -> HttpServiceConfig<HEADER_LIMIT_2, READ_BUF_LIMIT, WRITE_BUF_LIMIT> {
126        self.mutate_const_generic::<HEADER_LIMIT_2, READ_BUF_LIMIT, WRITE_BUF_LIMIT>()
127    }
128
129    /// Define the maximum number of concurrent HTTP/2 streams per connection.
130    pub fn h2_max_concurrent_streams(mut self, val: u32) -> Self {
131        self.h2_max_concurrent_streams = val;
132        self
133    }
134
135    /// Define the initial flow-control window size for HTTP/2 streams.
136    ///
137    /// Must not exceed 2^31-1 (2,147,483,647).
138    pub fn h2_initial_window_size(mut self, val: u32) -> Self {
139        self.h2_initial_window_size = val;
140        self
141    }
142
143    /// Define the maximum HTTP/2 frame size the server is willing to receive.
144    ///
145    /// Must be between 16,384 and 16,777,215 (inclusive).
146    pub fn h2_max_frame_size(mut self, val: u32) -> Self {
147        self.h2_max_frame_size = val;
148        self
149    }
150
151    /// Define the maximum size of HTTP/2 header list the server is willing to accept.
152    pub fn h2_max_header_list_size(mut self, val: u32) -> Self {
153        self.h2_max_header_list_size = val;
154        self
155    }
156
157    /// Enable peek into connection to figure out it's protocol regardless the outcome
158    /// of alpn negotiation.
159    ///
160    /// This API is used to bypass alpn setting from tls and enable Http/2 protocol over
161    /// plain Tcp connection.
162    pub fn peek_protocol(mut self) -> Self {
163        self.peek_protocol = true;
164        self
165    }
166
167    #[doc(hidden)]
168    /// A shortcut for mutating const generic params.
169    pub fn mutate_const_generic<
170        const HEADER_LIMIT2: usize,
171        const READ_BUF_LIMIT2: usize,
172        const WRITE_BUF_LIMIT2: usize,
173    >(
174        self,
175    ) -> HttpServiceConfig<HEADER_LIMIT2, READ_BUF_LIMIT2, WRITE_BUF_LIMIT2> {
176        HttpServiceConfig {
177            vectored_write: self.vectored_write,
178            keep_alive_timeout: self.keep_alive_timeout,
179            request_head_timeout: self.request_head_timeout,
180            tls_accept_timeout: self.tls_accept_timeout,
181            peek_protocol: self.peek_protocol,
182            h2_max_concurrent_streams: self.h2_max_concurrent_streams,
183            h2_initial_window_size: self.h2_initial_window_size,
184            h2_max_frame_size: self.h2_max_frame_size,
185            h2_max_header_list_size: self.h2_max_header_list_size,
186        }
187    }
188}