1use serde::{Deserialize, Serialize};
9use std::net::SocketAddr;
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct ServerConfig {
18 pub host: String,
19 pub port: u16,
20 pub max_connections: usize,
21 pub request_timeout_secs: u64,
22 pub body_limit_bytes: usize,
23 pub enable_cors: bool,
24 pub cors_allowed_origins: Vec<String>,
26 pub tls: Option<TlsConfig>,
27 pub cluster_tls: Option<ClusterTlsConfig>,
29 pub data_dir: Option<String>,
30 pub node_id: String,
32 pub node_name: Option<String>,
34 pub cluster_name: String,
36 pub peers: Vec<String>,
38 pub rate_limit_per_minute: u32,
40 pub login_rate_limit_per_minute: u32,
42 pub auth_required: bool,
44}
45
46impl Default for ServerConfig {
47 fn default() -> Self {
48 Self {
49 host: "127.0.0.1".to_string(),
50 port: 3000,
51 max_connections: 10000,
52 request_timeout_secs: 30,
53 body_limit_bytes: 10 * 1024 * 1024, enable_cors: true,
55 cors_allowed_origins: Vec::new(), tls: None,
57 cluster_tls: None,
58 data_dir: None,
59 node_id: generate_node_id(),
60 node_name: None,
61 cluster_name: "aegis-cluster".to_string(),
62 peers: Vec::new(),
63 rate_limit_per_minute: 100,
64 login_rate_limit_per_minute: 30,
65 auth_required: true,
66 }
67 }
68}
69
70fn generate_node_id() -> String {
72 use std::time::{SystemTime, UNIX_EPOCH};
73 let timestamp = SystemTime::now()
74 .duration_since(UNIX_EPOCH)
75 .unwrap_or_default()
76 .as_millis();
77 format!("node-{:x}", timestamp as u64)
78}
79
80impl ServerConfig {
81 pub fn new(host: &str, port: u16) -> Self {
83 Self {
84 host: host.to_string(),
85 port,
86 ..Default::default()
87 }
88 }
89
90 pub fn socket_addr(&self) -> SocketAddr {
92 format!("{}:{}", self.host, self.port)
93 .parse()
94 .unwrap_or_else(|_| SocketAddr::from(([127, 0, 0, 1], self.port)))
95 }
96
97 pub fn with_tls(mut self, cert_path: &str, key_path: &str) -> Self {
99 self.tls = Some(TlsConfig {
100 cert_path: cert_path.to_string(),
101 key_path: key_path.to_string(),
102 });
103 self
104 }
105
106 pub fn with_max_connections(mut self, max: usize) -> Self {
108 self.max_connections = max;
109 self
110 }
111
112 pub fn with_timeout(mut self, secs: u64) -> Self {
114 self.request_timeout_secs = secs;
115 self
116 }
117
118 pub fn with_data_dir(mut self, data_dir: Option<String>) -> Self {
120 self.data_dir = data_dir;
121 self
122 }
123
124 pub fn with_node_id(mut self, node_id: Option<String>) -> Self {
126 if let Some(id) = node_id {
127 self.node_id = id;
128 }
129 self
130 }
131
132 pub fn with_node_name(mut self, node_name: Option<String>) -> Self {
134 self.node_name = node_name;
135 self
136 }
137
138 pub fn with_cluster_name(mut self, cluster_name: String) -> Self {
140 self.cluster_name = cluster_name;
141 self
142 }
143
144 pub fn with_peers(mut self, peers: Vec<String>) -> Self {
146 self.peers = peers;
147 self
148 }
149
150 pub fn address(&self) -> String {
152 format!("{}:{}", self.host, self.port)
153 }
154
155 pub fn with_cluster_tls(mut self, cluster_tls: Option<ClusterTlsConfig>) -> Self {
157 self.cluster_tls = cluster_tls;
158 self
159 }
160
161 pub fn cluster_tls_enabled(&self) -> bool {
163 self.cluster_tls.as_ref().is_some_and(|c| c.enabled)
164 }
165}
166
167#[derive(Debug, Clone, Serialize, Deserialize)]
173pub struct TlsConfig {
174 pub cert_path: String,
175 pub key_path: String,
176}
177
178#[derive(Debug, Clone, Serialize, Deserialize)]
180pub struct ClusterTlsConfig {
181 pub enabled: bool,
183 pub ca_cert_path: Option<String>,
186 pub client_cert_path: Option<String>,
189 pub client_key_path: Option<String>,
192 pub danger_accept_invalid_certs: bool,
194}
195
196#[cfg(test)]
201mod tests {
202 use super::*;
203
204 #[test]
205 fn test_default_config() {
206 let config = ServerConfig::default();
207 assert_eq!(config.host, "127.0.0.1");
208 assert_eq!(config.port, 3000);
209 assert!(config.tls.is_none());
210 }
211
212 #[test]
213 fn test_socket_addr() {
214 let config = ServerConfig::new("0.0.0.0", 8080);
215 let addr = config.socket_addr();
216 assert_eq!(addr.port(), 8080);
217 }
218
219 #[test]
220 fn test_cluster_tls_config() {
221 let config = ServerConfig::default();
222 assert!(!config.cluster_tls_enabled());
223
224 let config_with_tls = config.with_cluster_tls(Some(ClusterTlsConfig {
225 enabled: true,
226 ca_cert_path: Some("/path/to/ca.pem".to_string()),
227 client_cert_path: Some("/path/to/cert.pem".to_string()),
228 client_key_path: Some("/path/to/key.pem".to_string()),
229 danger_accept_invalid_certs: false,
230 }));
231 assert!(config_with_tls.cluster_tls_enabled());
232
233 let config_disabled = ServerConfig::default().with_cluster_tls(Some(ClusterTlsConfig {
235 enabled: false,
236 ca_cert_path: None,
237 client_cert_path: None,
238 client_key_path: None,
239 danger_accept_invalid_certs: false,
240 }));
241 assert!(!config_disabled.cluster_tls_enabled());
242 }
243}