rush_sync_server/proxy/
manager.rs

1use crate::core::prelude::*;
2use crate::proxy::handler::ProxyServer;
3use crate::proxy::types::{ProxyConfig, ProxyRoute, ProxyTarget, RouteMap};
4use std::collections::HashMap;
5use std::sync::Arc;
6use tokio::sync::RwLock;
7
8pub struct ProxyManager {
9    config: ProxyConfig,
10    routes: Arc<RwLock<RouteMap>>,
11    targets: Arc<RwLock<HashMap<String, ProxyTarget>>>,
12}
13
14impl ProxyManager {
15    pub fn new(config: ProxyConfig) -> Self {
16        Self {
17            config,
18            routes: Arc::new(RwLock::new(HashMap::new())),
19            targets: Arc::new(RwLock::new(HashMap::new())),
20        }
21    }
22
23    pub async fn add_route(&self, server_name: &str, server_id: &str, port: u16) -> Result<()> {
24        let route = ProxyRoute {
25            subdomain: server_name.to_string(),
26            target_port: port,
27            server_id: server_id.to_string(),
28        };
29
30        let target = ProxyTarget {
31            name: server_name.to_string(),
32            port,
33            healthy: true,
34            last_check: std::time::SystemTime::now(),
35        };
36
37        {
38            let mut routes = self.routes.write().await;
39            routes.insert(server_name.to_string(), route);
40        }
41
42        {
43            let mut targets = self.targets.write().await;
44            targets.insert(server_name.to_string(), target);
45        }
46
47        log::info!(
48            "Added proxy route: {}.localhost -> 127.0.0.1:{}",
49            server_name,
50            port
51        );
52        Ok(())
53    }
54
55    pub async fn remove_route(&self, server_name: &str) -> Result<()> {
56        {
57            let mut routes = self.routes.write().await;
58            routes.remove(server_name);
59        }
60
61        {
62            let mut targets = self.targets.write().await;
63            targets.remove(server_name);
64        }
65
66        log::info!("Removed proxy route: {}.localhost", server_name);
67        Ok(())
68    }
69
70    pub async fn get_routes(&self) -> Vec<ProxyRoute> {
71        let routes = self.routes.read().await;
72        routes.values().cloned().collect()
73    }
74
75    pub async fn get_target_port(&self, subdomain: &str) -> Option<u16> {
76        let routes = self.routes.read().await;
77        routes.get(subdomain).map(|route| route.target_port)
78    }
79
80    pub fn get_config(&self) -> &ProxyConfig {
81        &self.config
82    }
83
84    pub async fn start_proxy_server(self: Arc<Self>) -> Result<()> {
85        if !self.config.enabled {
86            log::info!("Reverse Proxy disabled");
87            return Ok(());
88        }
89
90        let proxy_server = ProxyServer::new(Arc::clone(&self));
91
92        let https_port = self.config.port + self.config.https_port_offset;
93
94        log::info!("Starting Reverse Proxy:");
95        log::info!("  HTTP:  http://127.0.0.1:{}", self.config.port);
96        log::info!("  HTTPS: https://127.0.0.1:{}", https_port);
97
98        tokio::spawn(async move {
99            if let Err(e) = proxy_server.start_with_https().await {
100                log::error!("Proxy with HTTPS failed: {}", e);
101            }
102        });
103
104        log::info!(
105            "TLS certificate: .rss/certs/proxy-{}.cert",
106            self.config.port
107        );
108
109        Ok(())
110    }
111
112    pub async fn debug_routes(&self) {
113        let routes = self.routes.read().await;
114        log::info!("=== ACTIVE PROXY ROUTES ===");
115        if routes.is_empty() {
116            log::warn!("No routes registered!");
117        } else {
118            for (subdomain, route) in routes.iter() {
119                log::info!(
120                    "  {} -> 127.0.0.1:{} (server_id: {})",
121                    subdomain,
122                    route.target_port,
123                    route.server_id
124                );
125            }
126        }
127        log::info!("=== END ROUTES ===");
128    }
129}