nd_300/diagnostics/
proxy.rs1use 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 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 #[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 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 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 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}