From 1ebf63c70c552c95794325f40bbd278ba3e0c725 Mon Sep 17 00:00:00 2001 From: adamelmore <2363879+adamdottv@users.noreply.github.com> Date: Tue, 27 Jan 2026 14:55:50 -0600 Subject: [PATCH] fix(app): don't connect to localhost through vpn --- packages/desktop/src-tauri/src/lib.rs | 12 ++++++++++-- packages/desktop/src-tauri/src/main.rs | 27 +++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/packages/desktop/src-tauri/src/lib.rs b/packages/desktop/src-tauri/src/lib.rs index e086acd936..dab98f4a00 100644 --- a/packages/desktop/src-tauri/src/lib.rs +++ b/packages/desktop/src-tauri/src/lib.rs @@ -328,7 +328,15 @@ pub fn run() { .hidden_title(true); #[cfg(windows)] - let window_builder = window_builder.decorations(false); + let window_builder = window_builder + // Some VPNs set a global/system proxy that WebView2 applies even for loopback + // connections, which breaks the app's localhost sidecar server. + // Note: when setting additional args, we must re-apply wry's default + // `--disable-features=...` flags. + .additional_browser_args( + "--proxy-bypass-list=<-loopback> --disable-features=msWebOOUI,msPdfOOUI,msSmartScreenProtection", + ) + .decorations(false); let window = window_builder.build().expect("Failed to create window"); @@ -525,4 +533,4 @@ async fn spawn_local_server( break Ok(child); } } -} \ No newline at end of file +} diff --git a/packages/desktop/src-tauri/src/main.rs b/packages/desktop/src-tauri/src/main.rs index e3be4a44da..9ffee8aa5c 100644 --- a/packages/desktop/src-tauri/src/main.rs +++ b/packages/desktop/src-tauri/src/main.rs @@ -52,7 +52,32 @@ fn configure_display_backend() -> Option { } fn main() { - unsafe { std::env::set_var("NO_PROXY", "127.0.0.1,localhost,::1") }; + // Ensure loopback connections are never sent through proxy settings. + // Some VPNs/proxies set HTTP_PROXY/HTTPS_PROXY/ALL_PROXY without excluding localhost. + const LOOPBACK: [&str; 3] = ["127.0.0.1", "localhost", "::1"]; + + let upsert = |key: &str| { + let mut items = std::env::var(key) + .unwrap_or_default() + .split(',') + .map(|v| v.trim()) + .filter(|v| !v.is_empty()) + .map(|v| v.to_string()) + .collect::>(); + + for host in LOOPBACK { + if items.iter().any(|v| v.eq_ignore_ascii_case(host)) { + continue; + } + items.push(host.to_string()); + } + + // Safety: called during startup before any threads are spawned. + unsafe { std::env::set_var(key, items.join(",")) }; + }; + + upsert("NO_PROXY"); + upsert("no_proxy"); #[cfg(target_os = "linux")] {