rust_serv/proxy/
handler.rs1use super::config::ProxyConfig;
4
5#[derive(Debug, Clone)]
7pub struct ProxyHandler {
8 configs: Vec<ProxyConfig>,
10 default_timeout: std::time::Duration,
12}
13
14impl ProxyHandler {
15 pub fn new() -> Self {
17 Self {
18 configs: Vec::new(),
19 default_timeout: std::time::Duration::from_secs(30),
20 }
21 }
22
23 pub fn add_proxy(&mut self, config: ProxyConfig) {
25 self.configs.push(config);
26 }
27
28 pub fn remove_proxy(&mut self, path: &str) -> bool {
30 let len_before = self.configs.len();
31 self.configs.retain(|c| c.path != path);
32 self.configs.len() < len_before
33 }
34
35 pub fn find_match(&self, path: &str) -> Option<&ProxyConfig> {
37 self.configs.iter().find(|c| c.matches(path))
39 }
40
41 pub fn should_proxy(&self, path: &str) -> bool {
43 self.find_match(path).is_some()
44 }
45
46 pub fn get_target_url(&self, path: &str) -> Option<String> {
48 self.find_match(path).map(|c| c.build_target_url(path))
49 }
50
51 pub fn proxy_count(&self) -> usize {
53 self.configs.len()
54 }
55
56 pub fn clear(&mut self) {
58 self.configs.clear();
59 }
60
61 pub fn paths(&self) -> Vec<String> {
63 self.configs.iter().map(|c| c.path.clone()).collect()
64 }
65
66 pub fn has_proxy(&self, path: &str) -> bool {
68 self.configs.iter().any(|c| c.path == path)
69 }
70
71 pub fn set_default_timeout(&mut self, timeout: std::time::Duration) {
73 self.default_timeout = timeout;
74 }
75
76 pub fn default_timeout(&self) -> std::time::Duration {
78 self.default_timeout
79 }
80
81 pub fn configs_mut(&mut self) -> &mut Vec<ProxyConfig> {
83 &mut self.configs
84 }
85
86 pub fn configs(&self) -> &[ProxyConfig] {
88 &self.configs
89 }
90}
91
92impl Default for ProxyHandler {
93 fn default() -> Self {
94 Self::new()
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101
102 #[test]
103 fn test_handler_creation() {
104 let handler = ProxyHandler::new();
105 assert_eq!(handler.proxy_count(), 0);
106 }
107
108 #[test]
109 fn test_add_proxy() {
110 let mut handler = ProxyHandler::new();
111 handler.add_proxy(ProxyConfig::new("/api", "http://localhost:3000"));
112
113 assert_eq!(handler.proxy_count(), 1);
114 assert!(handler.has_proxy("/api"));
115 }
116
117 #[test]
118 fn test_remove_proxy() {
119 let mut handler = ProxyHandler::new();
120 handler.add_proxy(ProxyConfig::new("/api", "http://localhost:3000"));
121
122 assert!(handler.remove_proxy("/api"));
123 assert_eq!(handler.proxy_count(), 0);
124 assert!(!handler.has_proxy("/api"));
125 }
126
127 #[test]
128 fn test_remove_nonexistent() {
129 let mut handler = ProxyHandler::new();
130 assert!(!handler.remove_proxy("/nonexistent"));
131 }
132
133 #[test]
134 fn test_find_match() {
135 let mut handler = ProxyHandler::new();
136 handler.add_proxy(ProxyConfig::new("/api", "http://localhost:3000"));
137
138 let config = handler.find_match("/api/users").unwrap();
139 assert_eq!(config.path, "/api");
140 assert_eq!(config.target, "http://localhost:3000");
141 }
142
143 #[test]
144 fn test_find_match_no_match() {
145 let handler = ProxyHandler::new();
146 assert!(handler.find_match("/api").is_none());
147 }
148
149 #[test]
150 fn test_should_proxy() {
151 let mut handler = ProxyHandler::new();
152 handler.add_proxy(ProxyConfig::new("/api", "http://localhost:3000"));
153
154 assert!(handler.should_proxy("/api"));
155 assert!(handler.should_proxy("/api/users"));
156 assert!(!handler.should_proxy("/other"));
157 }
158
159 #[test]
160 fn test_get_target_url() {
161 let mut handler = ProxyHandler::new();
162 handler.add_proxy(ProxyConfig::new("/api", "http://localhost:3000"));
163
164 let url = handler.get_target_url("/api/users").unwrap();
165 assert_eq!(url, "http://localhost:3000/users");
166 }
167
168 #[test]
169 fn test_get_target_url_no_match() {
170 let handler = ProxyHandler::new();
171 assert!(handler.get_target_url("/api").is_none());
172 }
173
174 #[test]
175 fn test_multiple_proxies() {
176 let mut handler = ProxyHandler::new();
177
178 handler.add_proxy(ProxyConfig::new("/api", "http://api:3000"));
179 handler.add_proxy(ProxyConfig::new("/web", "http://web:8080"));
180 handler.add_proxy(ProxyConfig::new("/admin", "http://admin:9000"));
181
182 assert_eq!(handler.proxy_count(), 3);
183
184 assert!(handler.should_proxy("/api"));
185 assert!(handler.should_proxy("/web"));
186 assert!(handler.should_proxy("/admin"));
187 assert!(!handler.should_proxy("/other"));
188 }
189
190 #[test]
191 fn test_proxy_priority() {
192 let mut handler = ProxyHandler::new();
193
194 handler.add_proxy(ProxyConfig::new("/api/v1", "http://api-v1:3000"));
196 handler.add_proxy(ProxyConfig::new("/api", "http://api:3000"));
197
198 let config = handler.find_match("/api/v1/users").unwrap();
200 assert_eq!(config.path, "/api/v1");
201
202 let config = handler.find_match("/api/other").unwrap();
204 assert_eq!(config.path, "/api");
205 }
206
207 #[test]
208 fn test_clear() {
209 let mut handler = ProxyHandler::new();
210 handler.add_proxy(ProxyConfig::new("/api", "http://localhost:3000"));
211 handler.add_proxy(ProxyConfig::new("/web", "http://localhost:8080"));
212
213 handler.clear();
214
215 assert_eq!(handler.proxy_count(), 0);
216 assert!(!handler.should_proxy("/api"));
217 }
218
219 #[test]
220 fn test_paths() {
221 let mut handler = ProxyHandler::new();
222 handler.add_proxy(ProxyConfig::new("/api", "http://localhost:3000"));
223 handler.add_proxy(ProxyConfig::new("/web", "http://localhost:8080"));
224
225 let mut paths = handler.paths();
226 paths.sort();
227
228 assert_eq!(paths, vec!["/api", "/web"]);
229 }
230
231 #[test]
232 fn test_default_timeout() {
233 let mut handler = ProxyHandler::new();
234 assert_eq!(handler.default_timeout(), std::time::Duration::from_secs(30));
235
236 handler.set_default_timeout(std::time::Duration::from_secs(60));
237 assert_eq!(handler.default_timeout(), std::time::Duration::from_secs(60));
238 }
239
240 #[test]
241 fn test_default() {
242 let handler = ProxyHandler::default();
243 assert_eq!(handler.proxy_count(), 0);
244 }
245
246 #[test]
247 fn test_configs_access() {
248 let mut handler = ProxyHandler::new();
249 handler.add_proxy(ProxyConfig::new("/api", "http://localhost:3000"));
250
251 assert_eq!(handler.configs().len(), 1);
253
254 handler.configs_mut().push(ProxyConfig::new("/web", "http://localhost:8080"));
256 assert_eq!(handler.proxy_count(), 2);
257 }
258
259 #[test]
260 fn test_empty_path() {
261 let mut handler = ProxyHandler::new();
262 handler.add_proxy(ProxyConfig::new("/", "http://localhost:3000"));
263
264 assert!(handler.should_proxy("/"));
265 assert!(handler.should_proxy("/anything"));
266
267 let url = handler.get_target_url("/api").unwrap();
268 assert_eq!(url, "http://localhost:3000/api");
269 }
270}