use std::io::{self, ErrorKind};
use std::time::{Duration, Instant};
#[derive(Debug, Clone)]
pub struct Limits {
pub max_head_bytes: usize,
pub handshake_timeout: Duration,
pub idle_timeout: Duration,
pub connect_timeout: Duration,
pub max_connections: usize,
}
impl Limits {
pub(super) fn check(&self) -> io::Result<()> {
let now = Instant::now();
let sizes = [
("max_head_bytes", self.max_head_bytes),
("max_connections", self.max_connections),
];
let timeouts = [
("handshake_timeout", self.handshake_timeout),
("idle_timeout", self.idle_timeout),
("connect_timeout", self.connect_timeout),
];
let bad = sizes
.iter()
.find(|(_, n)| *n == 0)
.map(|(name, _)| name)
.or_else(|| {
timeouts
.iter()
.find(|(_, d)| d.is_zero() || now.checked_add(*d).is_none())
.map(|(name, _)| name)
});
match bad {
Some(name) => Err(io::Error::new(
ErrorKind::InvalidInput,
format!("proxy limit `{name}` is zero or too large"),
)),
None => Ok(()),
}
}
}
impl Default for Limits {
fn default() -> Self {
Self {
max_head_bytes: 16 * 1024,
handshake_timeout: Duration::from_secs(10),
idle_timeout: Duration::from_mins(2),
connect_timeout: Duration::from_secs(10),
max_connections: 256,
}
}
}