Skip to main content

nd_300/diagnostics/
proxy.rs

1use serde::Serialize;
2
3#[derive(Debug, Clone, Serialize)]
4pub struct ProxyConfig {
5    pub http_proxy: Option<String>,
6    pub https_proxy: Option<String>,
7    pub socks_proxy: Option<String>,
8    pub no_proxy: Option<String>,
9    pub pac_url: Option<String>,
10    pub proxy_enabled: bool,
11}
12
13pub async fn collect() -> Option<ProxyConfig> {
14    // Check environment variables first
15    let http_proxy = std::env::var("HTTP_PROXY")
16        .or_else(|_| std::env::var("http_proxy"))
17        .ok();
18    let https_proxy = std::env::var("HTTPS_PROXY")
19        .or_else(|_| std::env::var("https_proxy"))
20        .ok();
21    let socks_proxy = std::env::var("ALL_PROXY")
22        .or_else(|_| std::env::var("all_proxy"))
23        .ok();
24    let no_proxy = std::env::var("NO_PROXY")
25        .or_else(|_| std::env::var("no_proxy"))
26        .ok();
27
28    let mut config = ProxyConfig {
29        http_proxy,
30        https_proxy,
31        socks_proxy,
32        no_proxy,
33        pac_url: None,
34        proxy_enabled: false,
35    };
36
37    // Check OS-specific proxy settings
38    #[cfg(windows)]
39    {
40        check_windows_proxy(&mut config).await;
41    }
42
43    #[cfg(target_os = "macos")]
44    {
45        check_macos_proxy(&mut config).await;
46    }
47
48    config.proxy_enabled =
49        config.http_proxy.is_some() || config.https_proxy.is_some() || config.socks_proxy.is_some();
50
51    Some(config)
52}
53
54#[cfg(windows)]
55async fn check_windows_proxy(config: &mut ProxyConfig) {
56    // Check Windows registry via reg query
57    let mut cmd = tokio::process::Command::new("reg");
58    cmd.args([
59        "query",
60        r"HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings",
61        "/v",
62        "ProxyEnable",
63    ]);
64    if let Some(output) = super::util::run_with_timeout(cmd, super::util::QUICK).await {
65        let text = String::from_utf8_lossy(&output.stdout);
66        if text.contains("0x1") {
67            config.proxy_enabled = true;
68
69            // Get proxy server
70            let mut cmd = tokio::process::Command::new("reg");
71            cmd.args([
72                "query",
73                r"HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings",
74                "/v",
75                "ProxyServer",
76            ]);
77            if let Some(output) = super::util::run_with_timeout(cmd, super::util::QUICK).await {
78                let text = String::from_utf8_lossy(&output.stdout);
79                for line in text.lines() {
80                    if line.contains("ProxyServer") {
81                        if let Some(val) = line.split_whitespace().last() {
82                            if config.http_proxy.is_none() {
83                                config.http_proxy = Some(val.to_string());
84                            }
85                        }
86                    }
87                }
88            }
89
90            // Get PAC URL
91            let mut cmd = tokio::process::Command::new("reg");
92            cmd.args([
93                "query",
94                r"HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings",
95                "/v",
96                "AutoConfigURL",
97            ]);
98            if let Some(output) = super::util::run_with_timeout(cmd, super::util::QUICK).await {
99                let text = String::from_utf8_lossy(&output.stdout);
100                for line in text.lines() {
101                    if line.contains("AutoConfigURL") {
102                        config.pac_url = line.split_whitespace().last().map(|s| s.to_string());
103                    }
104                }
105            }
106        }
107    }
108}
109
110#[cfg(target_os = "macos")]
111async fn check_macos_proxy(config: &mut ProxyConfig) {
112    let mut cmd = tokio::process::Command::new("scutil");
113    cmd.args(["--proxy"]);
114    if let Some(output) = super::util::run_with_timeout(cmd, super::util::QUICK).await {
115        let text = String::from_utf8_lossy(&output.stdout);
116
117        for line in text.lines() {
118            let line = line.trim();
119            if line.contains("HTTPEnable") && line.contains("1") {
120                config.proxy_enabled = true;
121            }
122            if line.contains("HTTPProxy") {
123                config.http_proxy = line.split_once(':').map(|x| x.1.trim().to_string());
124            }
125            if line.contains("HTTPSProxy") {
126                config.https_proxy = line.split_once(':').map(|x| x.1.trim().to_string());
127            }
128            if line.contains("SOCKSProxy") {
129                config.socks_proxy = line.split_once(':').map(|x| x.1.trim().to_string());
130            }
131            if line.contains("ProxyAutoConfigURLString") {
132                config.pac_url = line.split_once(':').map(|x| x.1.trim().to_string());
133            }
134        }
135    }
136}