Release 2.7.3.1: harden proxy recovery, updates and local API.
Restore orphaned system proxy after crash, require update SHA-256, add macOS /api auth token, fix UDP ping false positives, HTTPS-only subscriptions, and keep the UI responsive during connect. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -82,7 +82,16 @@ func (c *darwinController) Disable() error {
|
||||
if !c.enabled {
|
||||
return nil
|
||||
}
|
||||
services := c.services
|
||||
return c.disableServices(c.services)
|
||||
}
|
||||
|
||||
func (c *darwinController) ForceDisable() error {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
return c.disableServices(nil)
|
||||
}
|
||||
|
||||
func (c *darwinController) disableServices(services []string) error {
|
||||
if len(services) == 0 {
|
||||
var err error
|
||||
services, err = listNetworkServices()
|
||||
|
||||
@@ -9,3 +9,4 @@ func newPlatform() Controller { return stubController{} }
|
||||
func (stubController) Enable(string) error { return ErrUnsupported }
|
||||
func (stubController) Disable() error { return nil }
|
||||
func (stubController) Enabled() bool { return false }
|
||||
func (stubController) ForceDisable() error { return nil }
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package sysproxy
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SentinelPath is written while Navis owns the OS system proxy.
|
||||
// Survives crash/kill so the next launch can clear a stuck proxy.
|
||||
func SentinelPath(cfgPath string) string {
|
||||
dir := filepath.Dir(strings.TrimSpace(cfgPath))
|
||||
if dir == "" || dir == "." {
|
||||
dir, _ = os.UserConfigDir()
|
||||
if dir == "" {
|
||||
dir = os.TempDir()
|
||||
}
|
||||
dir = filepath.Join(dir, "Navis")
|
||||
}
|
||||
return filepath.Join(dir, ".navis-proxy-on")
|
||||
}
|
||||
|
||||
// WriteSentinel marks that system proxy was enabled by Navis.
|
||||
func WriteSentinel(cfgPath, httpHostPort string) {
|
||||
path := SentinelPath(cfgPath)
|
||||
_ = os.MkdirAll(filepath.Dir(path), 0o755)
|
||||
_ = os.WriteFile(path, []byte(strings.TrimSpace(httpHostPort)+"\n"), 0o600)
|
||||
}
|
||||
|
||||
// ClearSentinel removes the ownership marker after a clean Disable.
|
||||
func ClearSentinel(cfgPath string) {
|
||||
_ = os.Remove(SentinelPath(cfgPath))
|
||||
}
|
||||
|
||||
// HasSentinel reports whether a previous session left the proxy marked on.
|
||||
func HasSentinel(cfgPath string) bool {
|
||||
_, err := os.Stat(SentinelPath(cfgPath))
|
||||
return err == nil
|
||||
}
|
||||
@@ -7,6 +7,9 @@ type Controller interface {
|
||||
Enable(httpHostPort string) error
|
||||
Disable() error
|
||||
Enabled() bool
|
||||
// ForceDisable turns off proxy settings even if this process did not Enable them
|
||||
// (used to recover after crash/kill when a sentinel file remains).
|
||||
ForceDisable() error
|
||||
}
|
||||
|
||||
// New returns a platform-specific controller.
|
||||
|
||||
@@ -95,6 +95,14 @@ func (c *windowsController) Disable() error {
|
||||
if !c.enabled {
|
||||
return nil
|
||||
}
|
||||
return c.disableLocked(true)
|
||||
}
|
||||
|
||||
func (c *windowsController) ForceDisable() error {
|
||||
return c.disableLocked(false)
|
||||
}
|
||||
|
||||
func (c *windowsController) disableLocked(restoreSaved bool) error {
|
||||
key, err := registry.OpenKey(registry.CURRENT_USER,
|
||||
`Software\Microsoft\Windows\CurrentVersion\Internet Settings`,
|
||||
registry.QUERY_VALUE|registry.SET_VALUE)
|
||||
@@ -103,7 +111,7 @@ func (c *windowsController) Disable() error {
|
||||
}
|
||||
defer key.Close()
|
||||
|
||||
if c.hadProxy {
|
||||
if restoreSaved && c.hadProxy {
|
||||
_ = key.SetDWordValue("ProxyEnable", uint32(c.oldEnable))
|
||||
if c.oldServer != "" {
|
||||
_ = key.SetStringValue("ProxyServer", c.oldServer)
|
||||
@@ -114,12 +122,21 @@ func (c *windowsController) Disable() error {
|
||||
_ = key.SetStringValue("ProxyOverride", c.oldOverride)
|
||||
}
|
||||
} else {
|
||||
_ = key.SetDWordValue("ProxyEnable", 0)
|
||||
// Crash recovery: if proxy still points at local Navis ports, clear it.
|
||||
server, _, _ := key.GetStringValue("ProxyServer")
|
||||
lower := strings.ToLower(server)
|
||||
if strings.Contains(lower, "127.0.0.1") || strings.Contains(lower, "localhost") {
|
||||
_ = key.SetDWordValue("ProxyEnable", 0)
|
||||
_ = key.DeleteValue("ProxyServer")
|
||||
} else if !restoreSaved {
|
||||
_ = key.SetDWordValue("ProxyEnable", 0)
|
||||
}
|
||||
}
|
||||
|
||||
_ = notifyInternetSettingsChanged()
|
||||
|
||||
c.enabled = false
|
||||
c.hadProxy = false
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user