14
httpProxyEnv = &envOnce{
15
names: []string{"HTTP_PROXY", "http_proxy"},
17
httpsProxyEnv = &envOnce{
18
names: []string{"HTTPS_PROXY", "https_proxy"},
20
noProxyEnv = &envOnce{
21
names: []string{"NO_PROXY", "no_proxy"},
31
func (e *envOnce) Get() string {
36
func (e *envOnce) init() {
37
for _, n := range e.names {
45
// This is basically the same as golang's ProxyFromEnvironment, except it
46
// doesn't fall back to http_proxy when https_proxy isn't around, which is
47
// incorrect behavior. It still respects HTTP_PROXY, HTTPS_PROXY, and NO_PROXY.
48
func ProxyFromEnvironment(req *http.Request) (*url.URL, error) {
49
return ProxyFromConfig("", "", "")(req)
52
func ProxyFromConfig(httpsProxy string, httpProxy string, noProxy string) func(req *http.Request) (*url.URL, error) {
53
return func(req *http.Request) (*url.URL, error) {
54
var proxy, port string
57
switch req.URL.Scheme {
61
proxy = httpsProxyEnv.Get()
67
proxy = httpProxyEnv.Get()
71
return nil, fmt.Errorf("unknown scheme %s", req.URL.Scheme)
83
use, err := useProxy(addr, noProxy)
91
proxyURL, err := url.Parse(proxy)
92
if err != nil || !strings.HasPrefix(proxyURL.Scheme, "http") {
93
// proxy was bogus. Try prepending "http://" to it and
94
// see if that parses correctly. If not, we fall
95
// through and complain about the original one.
96
if proxyURL, err := url.Parse("http://" + proxy); err == nil {
101
return nil, fmt.Errorf("invalid proxy address %q: %v", proxy, err)
107
func hasPort(s string) bool {
108
return strings.LastIndex(s, ":") > strings.LastIndex(s, "]")
111
func useProxy(addr string, noProxy string) (bool, error) {
113
noProxy = noProxyEnv.Get()
119
host, _, err := net.SplitHostPort(addr)
123
if host == "localhost" {
126
if ip := net.ParseIP(host); ip != nil {
136
addr = strings.ToLower(strings.TrimSpace(addr))
138
addr = addr[:strings.LastIndex(addr, ":")]
141
for _, p := range strings.Split(noProxy, ",") {
142
p = strings.ToLower(strings.TrimSpace(p))
147
p = p[:strings.LastIndex(p, ":")]
152
if p[0] == '.' && (strings.HasSuffix(addr, p) || addr == p[1:]) {
153
// noProxy ".foo.com" matches "bar.foo.com" or "foo.com"
156
if p[0] != '.' && strings.HasSuffix(addr, p) && addr[len(addr)-len(p)-1] == '.' {
157
// noProxy "foo.com" matches "bar.foo.com"