1use std::net::SocketAddr;
4use std::path::PathBuf;
5
6#[derive(Debug, Clone)]
8pub struct ProxyConfig {
9 pub listen_addr: SocketAddr,
11
12 pub target_addr: SocketAddr,
14
15 pub tls_enabled: bool,
17
18 pub tls_cert_file: Option<PathBuf>,
20
21 pub tls_key_file: Option<PathBuf>,
23
24 pub block_mode: bool,
26
27 pub log_file: Option<PathBuf>,
29
30 pub min_block_severity: crate::Severity,
32
33 pub verbose: bool,
35}
36
37impl Default for ProxyConfig {
38 fn default() -> Self {
39 Self {
40 listen_addr: "127.0.0.1:8080".parse().unwrap(),
41 target_addr: "127.0.0.1:3000".parse().unwrap(),
42 tls_enabled: false,
43 tls_cert_file: None,
44 tls_key_file: None,
45 block_mode: false,
46 log_file: None,
47 min_block_severity: crate::Severity::High,
48 verbose: false,
49 }
50 }
51}
52
53impl ProxyConfig {
54 pub fn new(listen_addr: SocketAddr, target_addr: SocketAddr) -> Self {
56 Self {
57 listen_addr,
58 target_addr,
59 ..Default::default()
60 }
61 }
62
63 pub fn with_tls(mut self) -> Self {
65 self.tls_enabled = true;
66 self
67 }
68
69 pub fn with_tls_files(mut self, cert: PathBuf, key: PathBuf) -> Self {
71 self.tls_enabled = true;
72 self.tls_cert_file = Some(cert);
73 self.tls_key_file = Some(key);
74 self
75 }
76
77 pub fn with_block_mode(mut self, min_severity: crate::Severity) -> Self {
79 self.block_mode = true;
80 self.min_block_severity = min_severity;
81 self
82 }
83
84 pub fn with_log_file(mut self, path: PathBuf) -> Self {
86 self.log_file = Some(path);
87 self
88 }
89
90 pub fn with_verbose(mut self) -> Self {
92 self.verbose = true;
93 self
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100 use std::path::PathBuf;
101
102 #[test]
103 fn test_default_config() {
104 let config = ProxyConfig::default();
105 assert_eq!(config.listen_addr.port(), 8080);
106 assert!(!config.tls_enabled);
107 assert!(!config.block_mode);
108 }
109
110 #[test]
111 fn test_config_builder() {
112 let config = ProxyConfig::new(
113 "0.0.0.0:9000".parse().unwrap(),
114 "127.0.0.1:3000".parse().unwrap(),
115 )
116 .with_tls()
117 .with_block_mode(crate::Severity::Critical)
118 .with_verbose();
119
120 assert_eq!(config.listen_addr.port(), 9000);
121 assert!(config.tls_enabled);
122 assert!(config.block_mode);
123 assert_eq!(config.min_block_severity, crate::Severity::Critical);
124 assert!(config.verbose);
125 }
126
127 #[test]
128 fn test_with_tls_files() {
129 let config = ProxyConfig::default().with_tls_files(
130 PathBuf::from("/path/to/cert.pem"),
131 PathBuf::from("/path/to/key.pem"),
132 );
133
134 assert!(config.tls_enabled);
135 assert_eq!(
136 config.tls_cert_file,
137 Some(PathBuf::from("/path/to/cert.pem"))
138 );
139 assert_eq!(config.tls_key_file, Some(PathBuf::from("/path/to/key.pem")));
140 }
141
142 #[test]
143 fn test_with_log_file() {
144 let config = ProxyConfig::default().with_log_file(PathBuf::from("/var/log/proxy.jsonl"));
145
146 assert_eq!(config.log_file, Some(PathBuf::from("/var/log/proxy.jsonl")));
147 }
148
149 #[test]
150 fn test_default_severity() {
151 let config = ProxyConfig::default();
152 assert_eq!(config.min_block_severity, crate::Severity::High);
153 }
154
155 #[test]
156 fn test_config_clone() {
157 let config = ProxyConfig::default()
158 .with_tls()
159 .with_block_mode(crate::Severity::Medium)
160 .with_verbose();
161
162 let cloned = config.clone();
163
164 assert_eq!(cloned.listen_addr, config.listen_addr);
165 assert_eq!(cloned.target_addr, config.target_addr);
166 assert_eq!(cloned.tls_enabled, config.tls_enabled);
167 assert_eq!(cloned.block_mode, config.block_mode);
168 assert_eq!(cloned.min_block_severity, config.min_block_severity);
169 assert_eq!(cloned.verbose, config.verbose);
170 }
171
172 #[test]
173 fn test_config_debug() {
174 let config = ProxyConfig::default();
175 let debug_str = format!("{:?}", config);
176
177 assert!(debug_str.contains("ProxyConfig"));
178 assert!(debug_str.contains("listen_addr"));
179 assert!(debug_str.contains("target_addr"));
180 }
181
182 #[test]
183 fn test_new_with_specific_addresses() {
184 let config = ProxyConfig::new(
185 "192.168.1.1:8888".parse().unwrap(),
186 "10.0.0.1:3333".parse().unwrap(),
187 );
188
189 assert_eq!(config.listen_addr.ip().to_string(), "192.168.1.1");
190 assert_eq!(config.listen_addr.port(), 8888);
191 assert_eq!(config.target_addr.ip().to_string(), "10.0.0.1");
192 assert_eq!(config.target_addr.port(), 3333);
193 }
194
195 #[test]
196 fn test_chained_builder() {
197 let log_path = PathBuf::from("/tmp/test.log");
198 let cert_path = PathBuf::from("/tmp/cert.pem");
199 let key_path = PathBuf::from("/tmp/key.pem");
200
201 let config = ProxyConfig::default()
202 .with_tls_files(cert_path.clone(), key_path.clone())
203 .with_block_mode(crate::Severity::Low)
204 .with_log_file(log_path.clone())
205 .with_verbose();
206
207 assert!(config.tls_enabled);
208 assert_eq!(config.tls_cert_file, Some(cert_path));
209 assert_eq!(config.tls_key_file, Some(key_path));
210 assert!(config.block_mode);
211 assert_eq!(config.min_block_severity, crate::Severity::Low);
212 assert_eq!(config.log_file, Some(log_path));
213 assert!(config.verbose);
214 }
215}