hyperi_rustlib/http_server/
config.rs1use serde::{Deserialize, Serialize};
12use std::time::Duration;
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
16#[allow(clippy::struct_excessive_bools)]
17pub struct HttpServerConfig {
18 pub bind_address: String,
20
21 #[serde(default = "default_request_timeout_ms")]
24 pub request_timeout_ms: u64,
25
26 #[serde(default = "default_keep_alive_timeout_ms")]
31 pub keep_alive_timeout_ms: u64,
32
33 #[serde(default = "default_max_connections")]
36 pub max_connections: usize,
37
38 #[serde(default = "default_true")]
40 pub enable_health_endpoints: bool,
41
42 #[serde(default)]
48 pub enable_metrics_endpoint: bool,
49
50 #[serde(default)]
52 pub enable_config_endpoint: bool,
53
54 #[serde(default = "default_true")]
59 pub enable_http2: bool,
60
61 #[serde(default)]
67 pub tls_cert_path: Option<String>,
68
69 #[serde(default)]
71 pub tls_key_path: Option<String>,
72
73 #[serde(default = "default_shutdown_timeout_ms")]
76 pub shutdown_timeout_ms: u64,
77}
78
79fn default_request_timeout_ms() -> u64 {
80 30_000
81}
82
83fn default_keep_alive_timeout_ms() -> u64 {
84 75_000
85}
86
87fn default_max_connections() -> usize {
88 10_000
89}
90
91fn default_shutdown_timeout_ms() -> u64 {
92 30_000
93}
94
95fn default_true() -> bool {
96 true
97}
98
99impl Default for HttpServerConfig {
100 fn default() -> Self {
101 Self {
102 bind_address: "0.0.0.0:8080".to_string(),
103 request_timeout_ms: default_request_timeout_ms(),
104 keep_alive_timeout_ms: default_keep_alive_timeout_ms(),
105 max_connections: default_max_connections(),
106 enable_health_endpoints: true,
107 enable_metrics_endpoint: false,
108 enable_config_endpoint: false,
109 enable_http2: true,
110 tls_cert_path: None,
111 tls_key_path: None,
112 shutdown_timeout_ms: default_shutdown_timeout_ms(),
113 }
114 }
115}
116
117impl HttpServerConfig {
118 #[must_use]
120 pub fn new(bind_address: impl Into<String>) -> Self {
121 Self {
122 bind_address: bind_address.into(),
123 ..Default::default()
124 }
125 }
126
127 #[must_use]
129 pub fn request_timeout(&self) -> Duration {
130 Duration::from_millis(self.request_timeout_ms)
131 }
132
133 #[must_use]
135 pub fn keep_alive_timeout(&self) -> Duration {
136 Duration::from_millis(self.keep_alive_timeout_ms)
137 }
138
139 #[must_use]
141 pub fn shutdown_timeout(&self) -> Duration {
142 Duration::from_millis(self.shutdown_timeout_ms)
143 }
144
145 #[must_use]
147 pub fn is_tls_enabled(&self) -> bool {
148 self.tls_cert_path.is_some() && self.tls_key_path.is_some()
149 }
150}
151
152#[cfg(test)]
153mod tests {
154 use super::*;
155
156 #[test]
157 fn test_default_config() {
158 let config = HttpServerConfig::default();
159 assert_eq!(config.bind_address, "0.0.0.0:8080");
160 assert_eq!(config.request_timeout_ms, 30_000);
161 assert_eq!(config.keep_alive_timeout_ms, 75_000);
162 assert_eq!(config.max_connections, 10_000);
163 assert!(config.enable_health_endpoints);
164 assert!(!config.enable_metrics_endpoint);
165 assert!(config.enable_http2);
166 assert!(!config.is_tls_enabled());
167 }
168
169 #[test]
170 fn test_new_with_address() {
171 let config = HttpServerConfig::new("127.0.0.1:3000");
172 assert_eq!(config.bind_address, "127.0.0.1:3000");
173 }
174
175 #[test]
176 fn test_tls_enabled() {
177 let mut config = HttpServerConfig::default();
178 assert!(!config.is_tls_enabled());
179
180 config.tls_cert_path = Some("/path/to/cert.pem".to_string());
181 assert!(!config.is_tls_enabled());
182
183 config.tls_key_path = Some("/path/to/key.pem".to_string());
184 assert!(config.is_tls_enabled());
185 }
186
187 #[test]
188 fn test_duration_conversions() {
189 let config = HttpServerConfig::default();
190 assert_eq!(config.request_timeout(), Duration::from_secs(30));
191 assert_eq!(config.keep_alive_timeout(), Duration::from_secs(75));
192 assert_eq!(config.shutdown_timeout(), Duration::from_secs(30));
193 }
194}