Просмотр исходного кода

fix(desktop): no proxy for connecting to sidecar (#9690)

Co-authored-by: Brendan Allan <[email protected]>
Adam 1 месяц назад
Родитель
Сommit
d6caaee816
1 измененных файлов с 27 добавлено и 6 удалено
  1. 27 6
      packages/desktop/src-tauri/src/lib.rs

+ 27 - 6
packages/desktop/src-tauri/src/lib.rs

@@ -156,6 +156,7 @@ fn spawn_sidecar(app: &AppHandle, port: u32, password: &str) -> CommandChild {
     println!("spawning sidecar on port {port}");
     println!("spawning sidecar on port {port}");
 
 
     let (mut rx, child) = cli::create_command(app, format!("serve --port {port}").as_str())
     let (mut rx, child) = cli::create_command(app, format!("serve --port {port}").as_str())
+        .env("OPENCODE_SERVER_USERNAME", "opencode")
         .env("OPENCODE_SERVER_PASSWORD", password)
         .env("OPENCODE_SERVER_PASSWORD", password)
         .spawn()
         .spawn()
         .expect("Failed to spawn opencode");
         .expect("Failed to spawn opencode");
@@ -197,17 +198,37 @@ fn spawn_sidecar(app: &AppHandle, port: u32, password: &str) -> CommandChild {
     child
     child
 }
 }
 
 
+fn url_is_localhost(url: &reqwest::Url) -> bool {
+    url.host_str().is_some_and(|host| {
+        host.eq_ignore_ascii_case("localhost")
+            || host
+                .parse::<std::net::IpAddr>()
+                .is_ok_and(|ip| ip.is_loopback())
+    })
+}
+
 async fn check_server_health(url: &str, password: Option<&str>) -> bool {
 async fn check_server_health(url: &str, password: Option<&str>) -> bool {
-    let health_url = format!("{}/global/health", url.trim_end_matches('/'));
-    let client = reqwest::Client::builder()
-        .timeout(Duration::from_secs(3))
-        .build();
+    let Ok(url) = reqwest::Url::parse(url) else {
+        return false;
+    };
+
+    let mut builder = reqwest::Client::builder().timeout(Duration::from_secs(3));
 
 
-    let Ok(client) = client else {
+    if url_is_localhost(&url) {
+        // Some environments set proxy variables (HTTP_PROXY/HTTPS_PROXY/ALL_PROXY) without
+        // excluding loopback. reqwest respects these by default, which can prevent the desktop
+        // app from reaching its own local sidecar server.
+        builder = builder.no_proxy();
+    };
+
+    let Ok(client) = builder.build() else {
+        return false;
+    };
+    let Ok(health_url) = url.join("/global/health") else {
         return false;
         return false;
     };
     };
 
 
-    let mut req = client.get(&health_url);
+    let mut req = client.get(health_url);
 
 
     if let Some(password) = password {
     if let Some(password) = password {
         req = req.basic_auth("opencode", Some(password));
         req = req.basic_auth("opencode", Some(password));