Skip to content

Commit f6698cf

Browse files
committed
vendor: import golang.org/x/net/proxy
Add golang.org/x/net/proxy from x/net git rev a689eb3bc4b5 Change-Id: I4ceb2cf5686042c545fe69868537a66e083139de Reviewed-on: https://go-review.googlesource.com/35552 Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent 36f55a8 commit f6698cf

File tree

6 files changed

+662
-0
lines changed

6 files changed

+662
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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.
4+
5+
package proxy
6+
7+
import (
8+
"net"
9+
)
10+
11+
type direct struct{}
12+
13+
// Direct is a direct proxy: one that makes network connections directly.
14+
var Direct = direct{}
15+
16+
func (direct) Dial(network, addr string) (net.Conn, error) {
17+
return net.Dial(network, addr)
18+
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
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.
4+
5+
package proxy
6+
7+
import (
8+
"net"
9+
"strings"
10+
)
11+
12+
// A PerHost directs connections to a default Dialer unless the hostname
13+
// requested matches one of a number of exceptions.
14+
type PerHost struct {
15+
def, bypass Dialer
16+
17+
bypassNetworks []*net.IPNet
18+
bypassIPs []net.IP
19+
bypassZones []string
20+
bypassHosts []string
21+
}
22+
23+
// NewPerHost returns a PerHost Dialer that directs connections to either
24+
// defaultDialer or bypass, depending on whether the connection matches one of
25+
// the configured rules.
26+
func NewPerHost(defaultDialer, bypass Dialer) *PerHost {
27+
return &PerHost{
28+
def: defaultDialer,
29+
bypass: bypass,
30+
}
31+
}
32+
33+
// Dial connects to the address addr on the given network through either
34+
// defaultDialer or bypass.
35+
func (p *PerHost) Dial(network, addr string) (c net.Conn, err error) {
36+
host, _, err := net.SplitHostPort(addr)
37+
if err != nil {
38+
return nil, err
39+
}
40+
41+
return p.dialerForRequest(host).Dial(network, addr)
42+
}
43+
44+
func (p *PerHost) dialerForRequest(host string) Dialer {
45+
if ip := net.ParseIP(host); ip != nil {
46+
for _, net := range p.bypassNetworks {
47+
if net.Contains(ip) {
48+
return p.bypass
49+
}
50+
}
51+
for _, bypassIP := range p.bypassIPs {
52+
if bypassIP.Equal(ip) {
53+
return p.bypass
54+
}
55+
}
56+
return p.def
57+
}
58+
59+
for _, zone := range p.bypassZones {
60+
if strings.HasSuffix(host, zone) {
61+
return p.bypass
62+
}
63+
if host == zone[1:] {
64+
// For a zone "example.com", we match "example.com"
65+
// too.
66+
return p.bypass
67+
}
68+
}
69+
for _, bypassHost := range p.bypassHosts {
70+
if bypassHost == host {
71+
return p.bypass
72+
}
73+
}
74+
return p.def
75+
}
76+
77+
// AddFromString parses a string that contains comma-separated values
78+
// specifying hosts that should use the bypass proxy. Each value is either an
79+
// IP address, a CIDR range, a zone (*.example.com) or a hostname
80+
// (localhost). A best effort is made to parse the string and errors are
81+
// ignored.
82+
func (p *PerHost) AddFromString(s string) {
83+
hosts := strings.Split(s, ",")
84+
for _, host := range hosts {
85+
host = strings.TrimSpace(host)
86+
if len(host) == 0 {
87+
continue
88+
}
89+
if strings.Contains(host, "/") {
90+
// We assume that it's a CIDR address like 127.0.0.0/8
91+
if _, net, err := net.ParseCIDR(host); err == nil {
92+
p.AddNetwork(net)
93+
}
94+
continue
95+
}
96+
if ip := net.ParseIP(host); ip != nil {
97+
p.AddIP(ip)
98+
continue
99+
}
100+
if strings.HasPrefix(host, "*.") {
101+
p.AddZone(host[1:])
102+
continue
103+
}
104+
p.AddHost(host)
105+
}
106+
}
107+
108+
// AddIP specifies an IP address that will use the bypass proxy. Note that
109+
// this will only take effect if a literal IP address is dialed. A connection
110+
// to a named host will never match an IP.
111+
func (p *PerHost) AddIP(ip net.IP) {
112+
p.bypassIPs = append(p.bypassIPs, ip)
113+
}
114+
115+
// AddNetwork specifies an IP range that will use the bypass proxy. Note that
116+
// this will only take effect if a literal IP address is dialed. A connection
117+
// to a named host will never match.
118+
func (p *PerHost) AddNetwork(net *net.IPNet) {
119+
p.bypassNetworks = append(p.bypassNetworks, net)
120+
}
121+
122+
// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of
123+
// "example.com" matches "example.com" and all of its subdomains.
124+
func (p *PerHost) AddZone(zone string) {
125+
if strings.HasSuffix(zone, ".") {
126+
zone = zone[:len(zone)-1]
127+
}
128+
if !strings.HasPrefix(zone, ".") {
129+
zone = "." + zone
130+
}
131+
p.bypassZones = append(p.bypassZones, zone)
132+
}
133+
134+
// AddHost specifies a hostname that will use the bypass proxy.
135+
func (p *PerHost) AddHost(host string) {
136+
if strings.HasSuffix(host, ".") {
137+
host = host[:len(host)-1]
138+
}
139+
p.bypassHosts = append(p.bypassHosts, host)
140+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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.
4+
5+
package proxy
6+
7+
import (
8+
"errors"
9+
"net"
10+
"reflect"
11+
"testing"
12+
)
13+
14+
type recordingProxy struct {
15+
addrs []string
16+
}
17+
18+
func (r *recordingProxy) Dial(network, addr string) (net.Conn, error) {
19+
r.addrs = append(r.addrs, addr)
20+
return nil, errors.New("recordingProxy")
21+
}
22+
23+
func TestPerHost(t *testing.T) {
24+
var def, bypass recordingProxy
25+
perHost := NewPerHost(&def, &bypass)
26+
perHost.AddFromString("localhost,*.zone,127.0.0.1,10.0.0.1/8,1000::/16")
27+
28+
expectedDef := []string{
29+
"example.com:123",
30+
"1.2.3.4:123",
31+
"[1001::]:123",
32+
}
33+
expectedBypass := []string{
34+
"localhost:123",
35+
"zone:123",
36+
"foo.zone:123",
37+
"127.0.0.1:123",
38+
"10.1.2.3:123",
39+
"[1000::]:123",
40+
}
41+
42+
for _, addr := range expectedDef {
43+
perHost.Dial("tcp", addr)
44+
}
45+
for _, addr := range expectedBypass {
46+
perHost.Dial("tcp", addr)
47+
}
48+
49+
if !reflect.DeepEqual(expectedDef, def.addrs) {
50+
t.Errorf("Hosts which went to the default proxy didn't match. Got %v, want %v", def.addrs, expectedDef)
51+
}
52+
if !reflect.DeepEqual(expectedBypass, bypass.addrs) {
53+
t.Errorf("Hosts which went to the bypass proxy didn't match. Got %v, want %v", bypass.addrs, expectedBypass)
54+
}
55+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
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.
4+
5+
// Package proxy provides support for a variety of protocols to proxy network
6+
// data.
7+
package proxy // import "golang.org/x/net/proxy"
8+
9+
import (
10+
"errors"
11+
"net"
12+
"net/url"
13+
"os"
14+
)
15+
16+
// A Dialer is a means to establish a connection.
17+
type Dialer interface {
18+
// Dial connects to the given address via the proxy.
19+
Dial(network, addr string) (c net.Conn, err error)
20+
}
21+
22+
// Auth contains authentication parameters that specific Dialers may require.
23+
type Auth struct {
24+
User, Password string
25+
}
26+
27+
// FromEnvironment returns the dialer specified by the proxy related variables in
28+
// the environment.
29+
func FromEnvironment() Dialer {
30+
allProxy := os.Getenv("all_proxy")
31+
if len(allProxy) == 0 {
32+
return Direct
33+
}
34+
35+
proxyURL, err := url.Parse(allProxy)
36+
if err != nil {
37+
return Direct
38+
}
39+
proxy, err := FromURL(proxyURL, Direct)
40+
if err != nil {
41+
return Direct
42+
}
43+
44+
noProxy := os.Getenv("no_proxy")
45+
if len(noProxy) == 0 {
46+
return proxy
47+
}
48+
49+
perHost := NewPerHost(proxy, Direct)
50+
perHost.AddFromString(noProxy)
51+
return perHost
52+
}
53+
54+
// proxySchemes is a map from URL schemes to a function that creates a Dialer
55+
// from a URL with such a scheme.
56+
var proxySchemes map[string]func(*url.URL, Dialer) (Dialer, error)
57+
58+
// RegisterDialerType takes a URL scheme and a function to generate Dialers from
59+
// a URL with that scheme and a forwarding Dialer. Registered schemes are used
60+
// by FromURL.
61+
func RegisterDialerType(scheme string, f func(*url.URL, Dialer) (Dialer, error)) {
62+
if proxySchemes == nil {
63+
proxySchemes = make(map[string]func(*url.URL, Dialer) (Dialer, error))
64+
}
65+
proxySchemes[scheme] = f
66+
}
67+
68+
// FromURL returns a Dialer given a URL specification and an underlying
69+
// Dialer for it to make network requests.
70+
func FromURL(u *url.URL, forward Dialer) (Dialer, error) {
71+
var auth *Auth
72+
if u.User != nil {
73+
auth = new(Auth)
74+
auth.User = u.User.Username()
75+
if p, ok := u.User.Password(); ok {
76+
auth.Password = p
77+
}
78+
}
79+
80+
switch u.Scheme {
81+
case "socks5":
82+
return SOCKS5("tcp", u.Host, auth, forward)
83+
}
84+
85+
// If the scheme doesn't match any of the built-in schemes, see if it
86+
// was registered by another package.
87+
if proxySchemes != nil {
88+
if f, ok := proxySchemes[u.Scheme]; ok {
89+
return f(u, forward)
90+
}
91+
}
92+
93+
return nil, errors.New("proxy: unknown scheme: " + u.Scheme)
94+
}

0 commit comments

Comments
 (0)