// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package proxy provides support for a variety of protocols to proxy network // data.
package proxy // import "golang.org/x/net/proxy" import ( ) // A Dialer is a means to establish a connection. // Custom dialers should also implement ContextDialer. type Dialer interface { // Dial connects to the given address via the proxy. Dial(network, addr string) (c net.Conn, err error) } // Auth contains authentication parameters that specific Dialers may require. type Auth struct { User, Password string } // FromEnvironment returns the dialer specified by the proxy-related // variables in the environment and makes underlying connections // directly. func () Dialer { return FromEnvironmentUsing(Direct) } // FromEnvironmentUsing returns the dialer specify by the proxy-related // variables in the environment and makes underlying connections // using the provided forwarding Dialer (for instance, a *net.Dialer // with desired configuration). func ( Dialer) Dialer { := allProxyEnv.Get() if len() == 0 { return } , := url.Parse() if != nil { return } , := FromURL(, ) if != nil { return } := noProxyEnv.Get() if len() == 0 { return } := NewPerHost(, ) .AddFromString() return } // proxySchemes is a map from URL schemes to a function that creates a Dialer // from a URL with such a scheme. var proxySchemes map[string]func(*url.URL, Dialer) (Dialer, error) // RegisterDialerType takes a URL scheme and a function to generate Dialers from // a URL with that scheme and a forwarding Dialer. Registered schemes are used // by FromURL. func ( string, func(*url.URL, Dialer) (Dialer, error)) { if proxySchemes == nil { proxySchemes = make(map[string]func(*url.URL, Dialer) (Dialer, error)) } proxySchemes[] = } // FromURL returns a Dialer given a URL specification and an underlying // Dialer for it to make network requests. func ( *url.URL, Dialer) (Dialer, error) { var *Auth if .User != nil { = new(Auth) .User = .User.Username() if , := .User.Password(); { .Password = } } switch .Scheme { case "socks5", "socks5h": := .Hostname() := .Port() if == "" { = "1080" } return SOCKS5("tcp", net.JoinHostPort(, ), , ) } // If the scheme doesn't match any of the built-in schemes, see if it // was registered by another package. if proxySchemes != nil { if , := proxySchemes[.Scheme]; { return (, ) } } return nil, errors.New("proxy: unknown scheme: " + .Scheme) } var ( allProxyEnv = &envOnce{ names: []string{"ALL_PROXY", "all_proxy"}, } noProxyEnv = &envOnce{ names: []string{"NO_PROXY", "no_proxy"}, } ) // envOnce looks up an environment variable (optionally by multiple // names) once. It mitigates expensive lookups on some platforms // (e.g. Windows). // (Borrowed from net/http/transport.go) type envOnce struct { names []string once sync.Once val string } func ( *envOnce) () string { .once.Do(.init) return .val } func ( *envOnce) () { for , := range .names { .val = os.Getenv() if .val != "" { return } } } // reset is used by tests func ( *envOnce) () { .once = sync.Once{} .val = "" }