I just re-wrote a library to easily retrieve the proxy settings of Internet Explorer (self answered SO question: https://stackoverflow.com/q/41764614/3207406).
GoDoc (with an example)
package ieproxy
import (
"os"
"strings"
"sync"
"golang.org/x/sys/windows/registry"
)
// StaticProxyConf containes the Windows configuration for static proxy
type StaticProxyConf struct {
// Is the proxy active?
Active bool
// Proxy address for each scheme (http, https)
// "" (empty string) is the fallback proxy
Protocols map[string]string
// Addresses not to be browsed via the proxy (comma-separated, like linux)
NoProxy string
}
// AutomaticProxyConf contains the Windows configuration for automatic proxy
type AutomaticProxyConf struct {
URL string // url of the .pac file
}
// WindowsProxyConf gathers the Windows configuration for proxy
type WindowsProxyConf struct {
Static StaticProxyConf // static configuration
Automatic AutomaticProxyConf // automatic configuration
}
type regeditValues struct {
ProxyServer string
ProxyOverride string
ProxyEnable uint64
AutoConfigURL string
}
var once sync.Once
var windowsProxyConf WindowsProxyConf
// GetConf retrieves the proxy configuration from the Windows Regedit
func getConf() WindowsProxyConf {
once.Do(parseRegedit)
return windowsProxyConf
}
// OverrideEnvWithStaticProxy writes new values to the
// http_proxy, https_proxy and no_proxy environment variables.
// The values are taken from the Windows Regedit (should be called in init() function)
func overrideEnvWithStaticProxy() {
conf := getConf()
if conf.Static.Active {
for _, scheme := range []string{"http", "https"} {
url, ok := conf.Static.Protocols[scheme]
if !ok {
url, ok = conf.Static.Protocols[""] // fallback conf
}
if ok {
os.Setenv(scheme+"_proxy", url)
}
}
if conf.Static.NoProxy != "" {
os.Setenv("no_proxy", conf.Static.NoProxy)
}
}
}
func parseRegedit() {
regedit, _ := readRegedit()
protocol := make(map[string]string)
for _, s := range strings.Split(regedit.ProxyServer, ";") {
if s == "" {
continue
}
pair := strings.SplitN(s, "=", 2)
if len(pair) > 1 {
protocol[pair[0]] = pair[1]
} else {
protocol[""] = pair[0]
}
}
windowsProxyConf.Static = StaticProxyConf{
Active: regedit.ProxyEnable > 0,
Protocols: protocol,
NoProxy: strings.Replace(regedit.ProxyOverride, ";", ",", -1), // to match linux style
}
windowsProxyConf.Automatic = AutomaticProxyConf{
URL: regedit.AutoConfigURL,
}
}
func readRegedit() (values regeditValues, err error) {
k, err := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Internet Settings`, registry.QUERY_VALUE)
if err != nil {
return
}
defer k.Close()
values.ProxyServer, _, err = k.GetStringValue("ProxyServer")
if err != nil && err != registry.ErrNotExist {
return
}
values.ProxyOverride, _, err = k.GetStringValue("ProxyOverride")
if err != nil && err != registry.ErrNotExist {
return
}
values.ProxyEnable, _, err = k.GetIntegerValue("ProxyEnable")
if err != nil && err != registry.ErrNotExist {
return
}
values.AutoConfigURL, _, err = k.GetStringValue("AutoConfigURL")
if err != nil && err != registry.ErrNotExist {
return
}
err = nil
return
}
I'm interested to know if the "go-style" can be improved and any other suggestions!
getConf
vsGetConf
.... hmmm \$\endgroup\$GetConf
callsgetConf
(for platform independency), but you are right that it isn't nice to read! \$\endgroup\$GetConf
is/was not defined in the code anywhere... so now it works after your edit, but I see that I had to go to the git repository to find that other file with theGetConf
declaration. \$\endgroup\$