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