folk_plugin_http/
config.rs1use std::net::SocketAddr;
2use std::path::PathBuf;
3use std::time::Duration;
4
5use ipnet::IpNet;
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
30#[serde(default)]
31pub struct HttpConfig {
32 pub listen: SocketAddr,
34 #[serde(with = "humantime_serde")]
36 pub read_timeout: Duration,
37 #[serde(with = "humantime_serde")]
39 pub write_timeout: Duration,
40 #[serde(with = "human_bytes")]
43 pub max_request_size: usize,
44 pub access_log: bool,
46 #[serde(default)]
50 pub trusted_proxies: Vec<IpNet>,
51 #[serde(default)]
54 pub tls: Option<TlsConfig>,
55 #[serde(default)]
57 pub h2c: bool,
58 #[serde(default)]
60 pub compression: CompressionConfig,
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize)]
65pub struct TlsConfig {
66 pub cert: PathBuf,
68 pub key: PathBuf,
70}
71
72#[derive(Debug, Clone, Serialize, Deserialize)]
74#[serde(default)]
75pub struct CompressionConfig {
76 pub enabled: bool,
78 pub algorithms: Vec<CompressionAlgorithm>,
81 #[serde(with = "human_bytes")]
83 pub min_size: usize,
84}
85
86impl Default for CompressionConfig {
87 fn default() -> Self {
88 Self {
89 enabled: false,
90 algorithms: vec![
91 CompressionAlgorithm::Gzip,
92 CompressionAlgorithm::Br,
93 CompressionAlgorithm::Zstd,
94 ],
95 min_size: 256,
96 }
97 }
98}
99
100#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
101#[serde(rename_all = "lowercase")]
102pub enum CompressionAlgorithm {
103 Gzip,
104 Br,
105 Zstd,
106 Deflate,
107}
108
109impl Default for HttpConfig {
110 fn default() -> Self {
111 Self {
112 listen: "0.0.0.0:8080".parse().unwrap(),
113 read_timeout: Duration::from_secs(10),
114 write_timeout: Duration::from_secs(30),
115 max_request_size: 10 * 1024 * 1024, access_log: false,
117 trusted_proxies: Vec::new(),
118 tls: None,
119 h2c: false,
120 compression: CompressionConfig::default(),
121 }
122 }
123}
124
125pub fn parse_byte_size(s: &str) -> Result<usize, String> {
128 let s = s.trim().to_lowercase();
129
130 if let Ok(n) = s.parse::<usize>() {
132 return Ok(n);
133 }
134
135 let (num_part, multiplier) = if let Some(n) = s.strip_suffix("gib") {
136 (n, 1024 * 1024 * 1024)
137 } else if let Some(n) = s.strip_suffix("gb") {
138 (n, 1024 * 1024 * 1024)
139 } else if let Some(n) = s.strip_suffix("mib") {
140 (n, 1024 * 1024)
141 } else if let Some(n) = s.strip_suffix("mb") {
142 (n, 1024 * 1024)
143 } else if let Some(n) = s.strip_suffix("kib") {
144 (n, 1024)
145 } else if let Some(n) = s.strip_suffix("kb") {
146 (n, 1024)
147 } else if let Some(n) = s.strip_suffix("b") {
148 (n, 1)
149 } else {
150 return Err(format!("invalid byte size: {s:?}"));
151 };
152
153 let num: usize = num_part
154 .trim()
155 .parse()
156 .map_err(|_| format!("invalid byte size number: {num_part:?}"))?;
157
158 Ok(num * multiplier)
159}
160
161mod human_bytes {
162 use serde::{Deserialize, Deserializer, Serializer, de};
163
164 pub fn serialize<S: Serializer>(value: &usize, ser: S) -> Result<S::Ok, S::Error> {
165 ser.serialize_u64(*value as u64)
166 }
167
168 pub fn deserialize<'de, D: Deserializer<'de>>(de: D) -> Result<usize, D::Error> {
169 #[derive(Deserialize)]
170 #[serde(untagged)]
171 enum ByteSize {
172 Str(String),
173 Num(usize),
174 }
175
176 match ByteSize::deserialize(de)? {
177 ByteSize::Num(n) => Ok(n),
178 ByteSize::Str(s) => super::parse_byte_size(&s).map_err(de::Error::custom),
179 }
180 }
181}