1use core::time::Duration;
4
5pub const DEFAULT_READ_BUF_LIMIT: usize = 1024 * 1024;
11
12pub const DEFAULT_WRITE_BUF_LIMIT: usize = 8192 + 4096 * 100;
16
17pub 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 pub const fn disable_vectored_write(mut self) -> Self {
68 self.vectored_write = false;
69 self
70 }
71
72 pub const fn keep_alive_timeout(mut self, dur: Duration) -> Self {
77 self.keep_alive_timeout = dur;
78 self
79 }
80
81 pub const fn request_head_timeout(mut self, dur: Duration) -> Self {
86 self.request_head_timeout = dur;
87 self
88 }
89
90 pub const fn tls_accept_timeout(mut self, dur: Duration) -> Self {
95 self.tls_accept_timeout = dur;
96 self
97 }
98
99 pub const fn max_read_buf_size<const READ_BUF_LIMIT_2: usize>(
111 self,
112 ) -> HttpServiceConfig<HEADER_LIMIT, READ_BUF_LIMIT_2, WRITE_BUF_LIMIT> {
113 assert!(READ_BUF_LIMIT_2 >= 32, "READ_BUF_LIMIT must be no less than 32 bytes");
114 h2_frame_read_buf_check(READ_BUF_LIMIT_2, self.h2_max_frame_size as _);
115 self.mutate_const_generic::<HEADER_LIMIT, READ_BUF_LIMIT_2, WRITE_BUF_LIMIT>()
116 }
117
118 pub const fn max_write_buf_size<const WRITE_BUF_LIMIT_2: usize>(
123 self,
124 ) -> HttpServiceConfig<HEADER_LIMIT, READ_BUF_LIMIT, WRITE_BUF_LIMIT_2> {
125 self.mutate_const_generic::<HEADER_LIMIT, READ_BUF_LIMIT, WRITE_BUF_LIMIT_2>()
126 }
127
128 pub const fn max_request_headers<const HEADER_LIMIT_2: usize>(
133 self,
134 ) -> HttpServiceConfig<HEADER_LIMIT_2, READ_BUF_LIMIT, WRITE_BUF_LIMIT> {
135 self.mutate_const_generic::<HEADER_LIMIT_2, READ_BUF_LIMIT, WRITE_BUF_LIMIT>()
136 }
137
138 pub const fn h2_max_concurrent_streams(mut self, val: u32) -> Self {
140 self.h2_max_concurrent_streams = val;
141 self
142 }
143
144 pub const fn h2_initial_window_size(mut self, val: u32) -> Self {
148 self.h2_initial_window_size = val;
149 self
150 }
151
152 pub const fn h2_max_frame_size(mut self, val: u32) -> Self {
165 h2_frame_read_buf_check(READ_BUF_LIMIT, val as _);
166 self.h2_max_frame_size = val;
167 self
168 }
169
170 pub const fn h2_max_header_list_size(mut self, val: u32) -> Self {
172 self.h2_max_header_list_size = val;
173 self
174 }
175
176 pub const fn peek_protocol(mut self) -> Self {
182 self.peek_protocol = true;
183 self
184 }
185
186 #[doc(hidden)]
187 pub const fn mutate_const_generic<
189 const HEADER_LIMIT2: usize,
190 const READ_BUF_LIMIT2: usize,
191 const WRITE_BUF_LIMIT2: usize,
192 >(
193 self,
194 ) -> HttpServiceConfig<HEADER_LIMIT2, READ_BUF_LIMIT2, WRITE_BUF_LIMIT2> {
195 HttpServiceConfig {
196 vectored_write: self.vectored_write,
197 keep_alive_timeout: self.keep_alive_timeout,
198 request_head_timeout: self.request_head_timeout,
199 tls_accept_timeout: self.tls_accept_timeout,
200 peek_protocol: self.peek_protocol,
201 h2_max_concurrent_streams: self.h2_max_concurrent_streams,
202 h2_initial_window_size: self.h2_initial_window_size,
203 h2_max_frame_size: self.h2_max_frame_size,
204 h2_max_header_list_size: self.h2_max_header_list_size,
205 }
206 }
207}
208
209const fn h2_frame_read_buf_check(read_buf_size: usize, h2_max_frame_size: usize) {
210 assert!(
211 read_buf_size >= (h2_max_frame_size + 9),
212 "max_read_buf_size must be at least h2_max_frame_size + 9 for HTTP2 to work"
213 );
214}