1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Package proxy provides support for a variety of protocols to proxy network
7 package proxy // import "golang.org/x/net/proxy"
17 // A Dialer is a means to establish a connection.
18 type Dialer interface {
19 // Dial connects to the given address via the proxy.
20 Dial(network, addr string) (c net.Conn, err error)
23 // Auth contains authentication parameters that specific Dialers may require.
28 // FromEnvironment returns the dialer specified by the proxy related variables in
30 func FromEnvironment() Dialer {
31 allProxy := allProxyEnv.Get()
32 if len(allProxy) == 0 {
36 proxyURL, err := url.Parse(allProxy)
40 proxy, err := FromURL(proxyURL, Direct)
45 noProxy := noProxyEnv.Get()
46 if len(noProxy) == 0 {
50 perHost := NewPerHost(proxy, Direct)
51 perHost.AddFromString(noProxy)
55 // proxySchemes is a map from URL schemes to a function that creates a Dialer
56 // from a URL with such a scheme.
57 var proxySchemes map[string]func(*url.URL, Dialer) (Dialer, error)
59 // RegisterDialerType takes a URL scheme and a function to generate Dialers from
60 // a URL with that scheme and a forwarding Dialer. Registered schemes are used
62 func RegisterDialerType(scheme string, f func(*url.URL, Dialer) (Dialer, error)) {
63 if proxySchemes == nil {
64 proxySchemes = make(map[string]func(*url.URL, Dialer) (Dialer, error))
66 proxySchemes[scheme] = f
69 // FromURL returns a Dialer given a URL specification and an underlying
70 // Dialer for it to make network requests.
71 func FromURL(u *url.URL, forward Dialer) (Dialer, error) {
75 auth.User = u.User.Username()
76 if p, ok := u.User.Password(); ok {
83 return SOCKS5("tcp", u.Host, auth, forward)
86 // If the scheme doesn't match any of the built-in schemes, see if it
87 // was registered by another package.
88 if proxySchemes != nil {
89 if f, ok := proxySchemes[u.Scheme]; ok {
94 return nil, errors.New("proxy: unknown scheme: " + u.Scheme)
98 allProxyEnv = &envOnce{
99 names: []string{"ALL_PROXY", "all_proxy"},
101 noProxyEnv = &envOnce{
102 names: []string{"NO_PROXY", "no_proxy"},
106 // envOnce looks up an environment variable (optionally by multiple
107 // names) once. It mitigates expensive lookups on some platforms
109 // (Borrowed from net/http/transport.go)
110 type envOnce struct {
116 func (e *envOnce) Get() string {
121 func (e *envOnce) init() {
122 for _, n := range e.names {
130 // reset is used by tests
131 func (e *envOnce) reset() {