1+ use serde:: { Deserialize , Serialize } ;
2+ use tauri:: State ;
3+ use rusqlite:: params;
4+
5+ use crate :: commands:: agents:: AgentDb ;
6+
7+ #[ derive( Debug , Serialize , Deserialize , Clone ) ]
8+ pub struct ProxySettings {
9+ pub http_proxy : Option < String > ,
10+ pub https_proxy : Option < String > ,
11+ pub no_proxy : Option < String > ,
12+ pub all_proxy : Option < String > ,
13+ pub enabled : bool ,
14+ }
15+
16+ impl Default for ProxySettings {
17+ fn default ( ) -> Self {
18+ Self {
19+ http_proxy : None ,
20+ https_proxy : None ,
21+ no_proxy : None ,
22+ all_proxy : None ,
23+ enabled : false ,
24+ }
25+ }
26+ }
27+
28+ /// Get proxy settings from the database
29+ #[ tauri:: command]
30+ pub async fn get_proxy_settings ( db : State < ' _ , AgentDb > ) -> Result < ProxySettings , String > {
31+ let conn = db. 0 . lock ( ) . map_err ( |e| e. to_string ( ) ) ?;
32+
33+ let mut settings = ProxySettings :: default ( ) ;
34+
35+ // Query each proxy setting
36+ let keys = vec ! [
37+ ( "proxy_enabled" , "enabled" ) ,
38+ ( "proxy_http" , "http_proxy" ) ,
39+ ( "proxy_https" , "https_proxy" ) ,
40+ ( "proxy_no" , "no_proxy" ) ,
41+ ( "proxy_all" , "all_proxy" ) ,
42+ ] ;
43+
44+ for ( db_key, field) in keys {
45+ if let Ok ( value) = conn. query_row (
46+ "SELECT value FROM app_settings WHERE key = ?1" ,
47+ params ! [ db_key] ,
48+ |row| row. get :: < _ , String > ( 0 ) ,
49+ ) {
50+ match field {
51+ "enabled" => settings. enabled = value == "true" ,
52+ "http_proxy" => settings. http_proxy = Some ( value) . filter ( |s| !s. is_empty ( ) ) ,
53+ "https_proxy" => settings. https_proxy = Some ( value) . filter ( |s| !s. is_empty ( ) ) ,
54+ "no_proxy" => settings. no_proxy = Some ( value) . filter ( |s| !s. is_empty ( ) ) ,
55+ "all_proxy" => settings. all_proxy = Some ( value) . filter ( |s| !s. is_empty ( ) ) ,
56+ _ => { }
57+ }
58+ }
59+ }
60+
61+ Ok ( settings)
62+ }
63+
64+ /// Save proxy settings to the database
65+ #[ tauri:: command]
66+ pub async fn save_proxy_settings (
67+ db : State < ' _ , AgentDb > ,
68+ settings : ProxySettings ,
69+ ) -> Result < ( ) , String > {
70+ let conn = db. 0 . lock ( ) . map_err ( |e| e. to_string ( ) ) ?;
71+
72+ // Save each setting
73+ let values = vec ! [
74+ ( "proxy_enabled" , settings. enabled. to_string( ) ) ,
75+ ( "proxy_http" , settings. http_proxy. clone( ) . unwrap_or_default( ) ) ,
76+ ( "proxy_https" , settings. https_proxy. clone( ) . unwrap_or_default( ) ) ,
77+ ( "proxy_no" , settings. no_proxy. clone( ) . unwrap_or_default( ) ) ,
78+ ( "proxy_all" , settings. all_proxy. clone( ) . unwrap_or_default( ) ) ,
79+ ] ;
80+
81+ for ( key, value) in values {
82+ conn. execute (
83+ "INSERT OR REPLACE INTO app_settings (key, value) VALUES (?1, ?2)" ,
84+ params ! [ key, value] ,
85+ ) . map_err ( |e| format ! ( "Failed to save {}: {}" , key, e) ) ?;
86+ }
87+
88+ // Apply the proxy settings immediately to the current process
89+ apply_proxy_settings ( & settings) ;
90+
91+ Ok ( ( ) )
92+ }
93+
94+ /// Apply proxy settings as environment variables
95+ pub fn apply_proxy_settings ( settings : & ProxySettings ) {
96+ log:: info!( "Applying proxy settings: enabled={}" , settings. enabled) ;
97+
98+ if !settings. enabled {
99+ // Clear proxy environment variables if disabled
100+ log:: info!( "Clearing proxy environment variables" ) ;
101+ std:: env:: remove_var ( "HTTP_PROXY" ) ;
102+ std:: env:: remove_var ( "HTTPS_PROXY" ) ;
103+ std:: env:: remove_var ( "NO_PROXY" ) ;
104+ std:: env:: remove_var ( "ALL_PROXY" ) ;
105+ // Also clear lowercase versions
106+ std:: env:: remove_var ( "http_proxy" ) ;
107+ std:: env:: remove_var ( "https_proxy" ) ;
108+ std:: env:: remove_var ( "no_proxy" ) ;
109+ std:: env:: remove_var ( "all_proxy" ) ;
110+ return ;
111+ }
112+
113+ // Ensure NO_PROXY includes localhost by default
114+ let mut no_proxy_list = vec ! [ "localhost" , "127.0.0.1" , "::1" , "0.0.0.0" ] ;
115+ if let Some ( user_no_proxy) = & settings. no_proxy {
116+ if !user_no_proxy. is_empty ( ) {
117+ no_proxy_list. push ( user_no_proxy. as_str ( ) ) ;
118+ }
119+ }
120+ let no_proxy_value = no_proxy_list. join ( "," ) ;
121+
122+ // Set proxy environment variables (uppercase is standard)
123+ if let Some ( http_proxy) = & settings. http_proxy {
124+ if !http_proxy. is_empty ( ) {
125+ log:: info!( "Setting HTTP_PROXY={}" , http_proxy) ;
126+ std:: env:: set_var ( "HTTP_PROXY" , http_proxy) ;
127+ }
128+ }
129+
130+ if let Some ( https_proxy) = & settings. https_proxy {
131+ if !https_proxy. is_empty ( ) {
132+ log:: info!( "Setting HTTPS_PROXY={}" , https_proxy) ;
133+ std:: env:: set_var ( "HTTPS_PROXY" , https_proxy) ;
134+ }
135+ }
136+
137+ // Always set NO_PROXY to include localhost
138+ log:: info!( "Setting NO_PROXY={}" , no_proxy_value) ;
139+ std:: env:: set_var ( "NO_PROXY" , & no_proxy_value) ;
140+
141+ if let Some ( all_proxy) = & settings. all_proxy {
142+ if !all_proxy. is_empty ( ) {
143+ log:: info!( "Setting ALL_PROXY={}" , all_proxy) ;
144+ std:: env:: set_var ( "ALL_PROXY" , all_proxy) ;
145+ }
146+ }
147+
148+ // Log current proxy environment variables for debugging
149+ log:: info!( "Current proxy environment variables:" ) ;
150+ for ( key, value) in std:: env:: vars ( ) {
151+ if key. contains ( "PROXY" ) || key. contains ( "proxy" ) {
152+ log:: info!( " {}={}" , key, value) ;
153+ }
154+ }
155+ }
0 commit comments