117 lines
4.1 KiB
Go
117 lines
4.1 KiB
Go
package ieproxy
|
|
|
|
/*
|
|
#cgo LDFLAGS: -framework CoreFoundation
|
|
#cgo LDFLAGS: -framework CFNetwork
|
|
#include <strings.h>
|
|
#include <CFNetwork/CFProxySupport.h>
|
|
*/
|
|
import "C"
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"sync"
|
|
"unsafe"
|
|
)
|
|
|
|
var once sync.Once
|
|
var darwinProxyConf ProxyConf
|
|
|
|
// GetConf retrieves the proxy configuration from the Windows Regedit
|
|
func getConf() ProxyConf {
|
|
once.Do(writeConf)
|
|
return darwinProxyConf
|
|
}
|
|
|
|
func cfStringGetGoString(cfStr C.CFStringRef) string {
|
|
retCString := (*C.char)(C.calloc(C.ulong(uint(128)), 1))
|
|
defer C.free(unsafe.Pointer(retCString))
|
|
|
|
C.CFStringGetCString(cfStr, retCString, C.long(128), C.kCFStringEncodingUTF8)
|
|
return C.GoString(retCString)
|
|
}
|
|
|
|
func cfNumberGetGoInt(cfNum C.CFNumberRef) int {
|
|
ret := 0
|
|
C.CFNumberGetValue(cfNum, C.kCFNumberIntType, unsafe.Pointer(&ret))
|
|
return ret
|
|
}
|
|
|
|
func cfArrayGetGoStrings(cfArray C.CFArrayRef) []string {
|
|
var ret []string
|
|
for i := 0; i < int(C.CFArrayGetCount(cfArray)); i++ {
|
|
cfStr := C.CFStringRef(C.CFArrayGetValueAtIndex(cfArray, C.long(i)))
|
|
if unsafe.Pointer(cfStr) != C.NULL {
|
|
ret = append(ret, cfStringGetGoString(cfStr))
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func writeConf() {
|
|
cfDictProxy := C.CFDictionaryRef(C.CFNetworkCopySystemProxySettings())
|
|
defer C.CFRelease(C.CFTypeRef(cfDictProxy))
|
|
|
|
cfNumHttpEnable := C.CFNumberRef(C.CFDictionaryGetValue(cfDictProxy, unsafe.Pointer(C.kCFNetworkProxiesHTTPEnable)))
|
|
if unsafe.Pointer(cfNumHttpEnable) != C.NULL && cfNumberGetGoInt(cfNumHttpEnable) > 0 {
|
|
darwinProxyConf.Static.Active = true
|
|
if darwinProxyConf.Static.Protocols == nil {
|
|
darwinProxyConf.Static.Protocols = make(map[string]string)
|
|
}
|
|
httpHost := C.CFStringRef(C.CFDictionaryGetValue(cfDictProxy, unsafe.Pointer(C.kCFNetworkProxiesHTTPProxy)))
|
|
httpPort := C.CFNumberRef(C.CFDictionaryGetValue(cfDictProxy, unsafe.Pointer(C.kCFNetworkProxiesHTTPPort)))
|
|
|
|
httpProxy := fmt.Sprintf("%s:%d", cfStringGetGoString(httpHost), cfNumberGetGoInt(httpPort))
|
|
darwinProxyConf.Static.Protocols["http"] = httpProxy
|
|
}
|
|
|
|
cfNumHttpsEnable := C.CFNumberRef(C.CFDictionaryGetValue(cfDictProxy, unsafe.Pointer(C.kCFNetworkProxiesHTTPSEnable)))
|
|
if unsafe.Pointer(cfNumHttpEnable) != C.NULL && cfNumberGetGoInt(cfNumHttpsEnable) > 0 {
|
|
darwinProxyConf.Static.Active = true
|
|
if darwinProxyConf.Static.Protocols == nil {
|
|
darwinProxyConf.Static.Protocols = make(map[string]string)
|
|
}
|
|
httpsHost := C.CFStringRef(C.CFDictionaryGetValue(cfDictProxy, unsafe.Pointer(C.kCFNetworkProxiesHTTPSProxy)))
|
|
httpsPort := C.CFNumberRef(C.CFDictionaryGetValue(cfDictProxy, unsafe.Pointer(C.kCFNetworkProxiesHTTPSPort)))
|
|
|
|
httpProxy := fmt.Sprintf("%s:%d", cfStringGetGoString(httpsHost), cfNumberGetGoInt(httpsPort))
|
|
darwinProxyConf.Static.Protocols["https"] = httpProxy
|
|
}
|
|
|
|
if darwinProxyConf.Static.Active {
|
|
cfArrayExceptionList := C.CFArrayRef(C.CFDictionaryGetValue(cfDictProxy, unsafe.Pointer(C.kCFNetworkProxiesExceptionsList)))
|
|
if unsafe.Pointer(cfArrayExceptionList) != C.NULL {
|
|
exceptionList := cfArrayGetGoStrings(cfArrayExceptionList)
|
|
darwinProxyConf.Static.NoProxy = strings.Join(exceptionList, ",")
|
|
}
|
|
}
|
|
|
|
cfNumPacEnable := C.CFNumberRef(C.CFDictionaryGetValue(cfDictProxy, unsafe.Pointer(C.kCFNetworkProxiesProxyAutoConfigEnable)))
|
|
if unsafe.Pointer(cfNumPacEnable) != C.NULL && cfNumberGetGoInt(cfNumPacEnable) > 0 {
|
|
cfStringPac := C.CFStringRef(C.CFDictionaryGetValue(cfDictProxy, unsafe.Pointer(C.kCFNetworkProxiesProxyAutoConfigURLString)))
|
|
if unsafe.Pointer(cfStringPac) != C.NULL {
|
|
pac := cfStringGetGoString(cfStringPac)
|
|
darwinProxyConf.Automatic.PreConfiguredURL = pac
|
|
darwinProxyConf.Automatic.Active = true
|
|
}
|
|
}
|
|
}
|
|
|
|
// OverrideEnvWithStaticProxy writes new values to the
|
|
// http_proxy, https_proxy and no_proxy environment variables.
|
|
// The values are taken from the MacOS System Preferences.
|
|
func overrideEnvWithStaticProxy(conf ProxyConf, setenv envSetter) {
|
|
if conf.Static.Active {
|
|
for _, scheme := range []string{"http", "https"} {
|
|
url := conf.Static.Protocols[scheme]
|
|
if url != "" {
|
|
setenv(scheme+"_proxy", url)
|
|
}
|
|
}
|
|
if conf.Static.NoProxy != "" {
|
|
setenv("no_proxy", conf.Static.NoProxy)
|
|
}
|
|
}
|
|
}
|