|
|
|
|
@ -19,6 +19,7 @@ import ( |
|
|
|
|
"time" |
|
|
|
|
|
|
|
|
|
"golang.org/x/net/http/httpproxy" |
|
|
|
|
"tailscale.com/util/mak" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// InvalidateCache invalidates the package-level cache for ProxyFromEnvironment.
|
|
|
|
|
@ -117,10 +118,33 @@ func SetSelfProxy(addrs ...string) { |
|
|
|
|
// For example, WPAD PAC files on Windows.
|
|
|
|
|
var sysProxyFromEnv func(*http.Request) (*url.URL, error) |
|
|
|
|
|
|
|
|
|
// These variables track whether we've printed a log message for a given proxy
|
|
|
|
|
// URL; we only print them once to avoid log spam.
|
|
|
|
|
var ( |
|
|
|
|
logMessageMu sync.Mutex |
|
|
|
|
logMessagePrinted map[string]bool |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// ProxyFromEnvironment is like the standard library's http.ProxyFromEnvironment
|
|
|
|
|
// but additionally does OS-specific proxy lookups if the environment variables
|
|
|
|
|
// alone don't specify a proxy.
|
|
|
|
|
func ProxyFromEnvironment(req *http.Request) (*url.URL, error) { |
|
|
|
|
func ProxyFromEnvironment(req *http.Request) (ret *url.URL, _ error) { |
|
|
|
|
defer func() { |
|
|
|
|
if ret == nil { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ss := ret.String() |
|
|
|
|
|
|
|
|
|
logMessageMu.Lock() |
|
|
|
|
defer logMessageMu.Unlock() |
|
|
|
|
if logMessagePrinted[ss] { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
log.Printf("tshttpproxy: using proxy %q for URL: %q", ss, req.URL.String()) |
|
|
|
|
mak.Set(&logMessagePrinted, ss, true) |
|
|
|
|
}() |
|
|
|
|
|
|
|
|
|
localProxyFunc := getProxyFunc() |
|
|
|
|
u, err := localProxyFunc(req.URL) |
|
|
|
|
if u != nil && err == nil { |
|
|
|
|
|