Skip to main content

icap_rs/server/
timeouts.rs

1//! Server-side timeout configuration.
2//!
3//! Group all per-connection deadlines in one struct so they can be configured
4//! at once via [`ServerBuilder::with_timeouts`](super::builder::ServerBuilder::with_timeouts)
5//! and stored inside the [`Server`](super::Server) as a single field.
6//!
7//! All fields default to `None` (no timeout). TLS handshake timeouts are
8//! configured on [`ServerTlsConfig`](crate::tls::ServerTlsConfig).
9
10use std::time::Duration;
11
12/// Aggregated server deadlines applied per connection and for graceful shutdown.
13///
14/// - [`header_read`](Self::header_read): max time to receive a full ICAP header
15///   block (`CRLFCRLF`) once the request has started arriving. Mitigates
16///   slowloris-style header attacks.
17/// - [`body_read`](Self::body_read): max time budget for reading the encapsulated
18///   body of a single request (chunked decoding included).
19/// - [`write`](Self::write): max time to write any single response chunk to the
20///   client.
21/// - [`idle_keepalive`](Self::idle_keepalive): max time to wait for the **first**
22///   byte of the next request on a kept-alive connection (after the previous
23///   response was flushed). Used only for the leading read; once any bytes
24///   arrive, [`header_read`](Self::header_read) governs the rest of the header
25///   block.
26/// - [`shutdown_drain`](Self::shutdown_drain): max time to wait for in-flight
27///   requests to finish after a shutdown signal. If the deadline expires, the
28///   remaining connections are cancelled. When `None` the server waits
29///   indefinitely.
30#[derive(Debug, Clone, Default)]
31#[must_use]
32pub struct ServerTimeouts {
33    pub header_read: Option<Duration>,
34    pub body_read: Option<Duration>,
35    pub write: Option<Duration>,
36    pub idle_keepalive: Option<Duration>,
37    pub shutdown_drain: Option<Duration>,
38}
39
40impl ServerTimeouts {
41    /// Construct a `ServerTimeouts` with every deadline disabled (`None`).
42    pub const fn new() -> Self {
43        Self {
44            header_read: None,
45            body_read: None,
46            write: None,
47            idle_keepalive: None,
48            shutdown_drain: None,
49        }
50    }
51
52    /// Set the [`header_read`](Self::header_read) deadline.
53    ///
54    /// Limits how long the server waits to receive a full ICAP header block
55    /// (`CRLFCRLF`) once the request has started arriving.
56    pub const fn with_header_read(mut self, dur: Duration) -> Self {
57        self.header_read = Some(dur);
58        self
59    }
60
61    /// Set the [`body_read`](Self::body_read) deadline.
62    ///
63    /// Bounds the time budget for reading the encapsulated body of a single
64    /// request, including chunked decoding.
65    pub const fn with_body_read(mut self, dur: Duration) -> Self {
66        self.body_read = Some(dur);
67        self
68    }
69
70    /// Set the [`write`](Self::write) deadline.
71    ///
72    /// Bounds the time to write any single response chunk to the client.
73    pub const fn with_write(mut self, dur: Duration) -> Self {
74        self.write = Some(dur);
75        self
76    }
77
78    /// Set the [`idle_keepalive`](Self::idle_keepalive) deadline.
79    ///
80    /// Bounds how long the server waits for the **first** byte of the next
81    /// request on a kept-alive connection after the previous response was
82    /// flushed. Once any byte arrives, [`with_header_read`](Self::with_header_read)
83    /// governs the rest of the header block.
84    pub const fn with_idle_keepalive(mut self, dur: Duration) -> Self {
85        self.idle_keepalive = Some(dur);
86        self
87    }
88
89    /// Set the [`shutdown_drain`](Self::shutdown_drain) deadline.
90    ///
91    /// Bounds how long the server waits for active connections to finish after
92    /// a shutdown signal. Connections still in flight when the deadline expires
93    /// are cancelled. When not set the drain waits indefinitely.
94    pub const fn with_shutdown_drain(mut self, dur: Duration) -> Self {
95        self.shutdown_drain = Some(dur);
96        self
97    }
98}