]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: replace SOCKS client implementation
authorMikio Hara <mikioh.mikioh@gmail.com>
Tue, 18 Apr 2017 20:35:58 +0000 (05:35 +0900)
committerBrad Fitzpatrick <bradfitz@golang.org>
Fri, 6 Apr 2018 23:03:17 +0000 (23:03 +0000)
This change replaces the vendored socks client implementation with the
bundle of golang.org/x/net/internal/socks package which contains fixes
for 19354 and 11682.

golang.org/x/net/internal/socks becomes socks_bundle.go.

At git rev 61147c4. (golang.org/cl/38278)

Updates #11682.
Updates #18508.
Updates #19354.
Fixes #19688.
Updates #21333.

Change-Id: I8cf6c3f5eb87c24685a7592be015729f84fbed77
Reviewed-on: https://go-review.googlesource.com/41031
Run-TryBot: Mikio Hara <mikioh.mikioh@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/go/build/deps_test.go
src/net/http/socks_bundle.go [new file with mode: 0644]
src/net/http/transport.go
src/net/http/transport_test.go
src/vendor/golang_org/x/net/proxy/direct.go [deleted file]
src/vendor/golang_org/x/net/proxy/per_host.go [deleted file]
src/vendor/golang_org/x/net/proxy/per_host_test.go [deleted file]
src/vendor/golang_org/x/net/proxy/proxy.go [deleted file]
src/vendor/golang_org/x/net/proxy/proxy_test.go [deleted file]
src/vendor/golang_org/x/net/proxy/socks5.go [deleted file]

index 938762569d6a2e79177cd55ae46c2eb7b178dd0c..1105de16daa343a56f21f8a275edf94dbb8be055 100644 (file)
@@ -403,7 +403,6 @@ var pkgDeps = map[string][]string{
                "golang_org/x/net/http2/hpack",
                "golang_org/x/net/idna",
                "golang_org/x/net/lex/httplex",
-               "golang_org/x/net/proxy",
                "golang_org/x/text/unicode/norm",
                "golang_org/x/text/width",
                "internal/nettrace",
diff --git a/src/net/http/socks_bundle.go b/src/net/http/socks_bundle.go
new file mode 100644 (file)
index 0000000..5c3830a
--- /dev/null
@@ -0,0 +1,421 @@
+// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT.
+//go:generate bundle -o socks_bundle.go -dst http -prefix socks -underscore golang.org/x/net/internal/socks
+
+// Package socks provides a SOCKS version 5 client implementation.
+//
+// SOCKS protocol version 5 is defined in RFC 1928.
+// Username/Password authentication for SOCKS version 5 is defined in
+// RFC 1929.
+//
+
+package http
+
+import (
+       "context"
+       "errors"
+       "io"
+       "net"
+       "strconv"
+       "time"
+)
+
+var (
+       socksnoDeadline   = time.Time{}
+       socksaLongTimeAgo = time.Unix(1, 0)
+)
+
+func (d *socksDialer) connect(ctx context.Context, c net.Conn, address string) (_ net.Addr, ctxErr error) {
+       host, port, err := sockssplitHostPort(address)
+       if err != nil {
+               return nil, err
+       }
+       if deadline, ok := ctx.Deadline(); ok && !deadline.IsZero() {
+               c.SetDeadline(deadline)
+               defer c.SetDeadline(socksnoDeadline)
+       }
+       if ctx != context.Background() {
+               errCh := make(chan error, 1)
+               done := make(chan struct{})
+               defer func() {
+                       close(done)
+                       if ctxErr == nil {
+                               ctxErr = <-errCh
+                       }
+               }()
+               go func() {
+                       select {
+                       case <-ctx.Done():
+                               c.SetDeadline(socksaLongTimeAgo)
+                               errCh <- ctx.Err()
+                       case <-done:
+                               errCh <- nil
+                       }
+               }()
+       }
+
+       b := make([]byte, 0, 6+len(host)) // the size here is just an estimate
+       b = append(b, socksVersion5)
+       if len(d.AuthMethods) == 0 || d.Authenticate == nil {
+               b = append(b, 1, byte(socksAuthMethodNotRequired))
+       } else {
+               ams := d.AuthMethods
+               if len(ams) > 255 {
+                       return nil, errors.New("too many authentication methods")
+               }
+               b = append(b, byte(len(ams)))
+               for _, am := range ams {
+                       b = append(b, byte(am))
+               }
+       }
+       if _, ctxErr = c.Write(b); ctxErr != nil {
+               return
+       }
+
+       if _, ctxErr = io.ReadFull(c, b[:2]); ctxErr != nil {
+               return
+       }
+       if b[0] != socksVersion5 {
+               return nil, errors.New("unexpected protocol version " + strconv.Itoa(int(b[0])))
+       }
+       am := socksAuthMethod(b[1])
+       if am == socksAuthMethodNoAcceptableMethods {
+               return nil, errors.New("no acceptable authentication methods")
+       }
+       if d.Authenticate != nil {
+               if ctxErr = d.Authenticate(ctx, c, am); ctxErr != nil {
+                       return
+               }
+       }
+
+       b = b[:0]
+       b = append(b, socksVersion5, byte(d.cmd), 0)
+       if ip := net.ParseIP(host); ip != nil {
+               if ip4 := ip.To4(); ip4 != nil {
+                       b = append(b, socksAddrTypeIPv4)
+                       b = append(b, ip4...)
+               } else if ip6 := ip.To16(); ip6 != nil {
+                       b = append(b, socksAddrTypeIPv6)
+                       b = append(b, ip6...)
+               } else {
+                       return nil, errors.New("unknown address type")
+               }
+       } else {
+               if len(host) > 255 {
+                       return nil, errors.New("FQDN too long")
+               }
+               b = append(b, socksAddrTypeFQDN)
+               b = append(b, byte(len(host)))
+               b = append(b, host...)
+       }
+       b = append(b, byte(port>>8), byte(port))
+       if _, ctxErr = c.Write(b); ctxErr != nil {
+               return
+       }
+
+       if _, ctxErr = io.ReadFull(c, b[:4]); ctxErr != nil {
+               return
+       }
+       if b[0] != socksVersion5 {
+               return nil, errors.New("unexpected protocol version " + strconv.Itoa(int(b[0])))
+       }
+       if cmdErr := socksReply(b[1]); cmdErr != socksStatusSucceeded {
+               return nil, errors.New("unknown error " + cmdErr.String())
+       }
+       if b[2] != 0 {
+               return nil, errors.New("non-zero reserved field")
+       }
+       l := 2
+       var a socksAddr
+       switch b[3] {
+       case socksAddrTypeIPv4:
+               l += net.IPv4len
+               a.IP = make(net.IP, net.IPv4len)
+       case socksAddrTypeIPv6:
+               l += net.IPv6len
+               a.IP = make(net.IP, net.IPv6len)
+       case socksAddrTypeFQDN:
+               if _, err := io.ReadFull(c, b[:1]); err != nil {
+                       return nil, err
+               }
+               l += int(b[0])
+       default:
+               return nil, errors.New("unknown address type " + strconv.Itoa(int(b[3])))
+       }
+       if cap(b) < l {
+               b = make([]byte, l)
+       } else {
+               b = b[:l]
+       }
+       if _, ctxErr = io.ReadFull(c, b); ctxErr != nil {
+               return
+       }
+       if a.IP != nil {
+               copy(a.IP, b)
+       } else {
+               a.Name = string(b[:len(b)-2])
+       }
+       a.Port = int(b[len(b)-2])<<8 | int(b[len(b)-1])
+       return &a, nil
+}
+
+func sockssplitHostPort(address string) (string, int, error) {
+       host, port, err := net.SplitHostPort(address)
+       if err != nil {
+               return "", 0, err
+       }
+       portnum, err := strconv.Atoi(port)
+       if err != nil {
+               return "", 0, err
+       }
+       if 1 > portnum || portnum > 0xffff {
+               return "", 0, errors.New("port number out of range " + port)
+       }
+       return host, portnum, nil
+}
+
+// A Command represents a SOCKS command.
+type socksCommand int
+
+func (cmd socksCommand) String() string {
+       switch cmd {
+       case socksCmdConnect:
+               return "socks connect"
+       case sockscmdBind:
+               return "socks bind"
+       default:
+               return "socks " + strconv.Itoa(int(cmd))
+       }
+}
+
+// An AuthMethod represents a SOCKS authentication method.
+type socksAuthMethod int
+
+// A Reply represents a SOCKS command reply code.
+type socksReply int
+
+func (code socksReply) String() string {
+       switch code {
+       case socksStatusSucceeded:
+               return "succeeded"
+       case 0x01:
+               return "general SOCKS server failure"
+       case 0x02:
+               return "connection not allowed by ruleset"
+       case 0x03:
+               return "network unreachable"
+       case 0x04:
+               return "host unreachable"
+       case 0x05:
+               return "connection refused"
+       case 0x06:
+               return "TTL expired"
+       case 0x07:
+               return "command not supported"
+       case 0x08:
+               return "address type not supported"
+       default:
+               return "unknown code: " + strconv.Itoa(int(code))
+       }
+}
+
+// Wire protocol constants.
+const (
+       socksVersion5 = 0x05
+
+       socksAddrTypeIPv4 = 0x01
+       socksAddrTypeFQDN = 0x03
+       socksAddrTypeIPv6 = 0x04
+
+       socksCmdConnect socksCommand = 0x01 // establishes an active-open forward proxy connection
+       sockscmdBind    socksCommand = 0x02 // establishes a passive-open forward proxy connection
+
+       socksAuthMethodNotRequired         socksAuthMethod = 0x00 // no authentication required
+       socksAuthMethodUsernamePassword    socksAuthMethod = 0x02 // use username/password
+       socksAuthMethodNoAcceptableMethods socksAuthMethod = 0xff // no acceptable authetication methods
+
+       socksStatusSucceeded socksReply = 0x00
+)
+
+// An Addr represents a SOCKS-specific address.
+// Either Name or IP is used exclusively.
+type socksAddr struct {
+       Name string // fully-qualified domain name
+       IP   net.IP
+       Port int
+}
+
+func (a *socksAddr) Network() string { return "socks" }
+
+func (a *socksAddr) String() string {
+       if a == nil {
+               return "<nil>"
+       }
+       port := strconv.Itoa(a.Port)
+       if a.IP == nil {
+               return net.JoinHostPort(a.Name, port)
+       }
+       return net.JoinHostPort(a.IP.String(), port)
+}
+
+// A Conn represents a forward proxy connection.
+type socksConn struct {
+       net.Conn
+
+       boundAddr net.Addr
+}
+
+// BoundAddr returns the address assigned by the proxy server for
+// connecting to the command target address from the proxy server.
+func (c *socksConn) BoundAddr() net.Addr {
+       if c == nil {
+               return nil
+       }
+       return c.boundAddr
+}
+
+// A Dialer holds SOCKS-specific options.
+type socksDialer struct {
+       cmd          socksCommand // either CmdConnect or cmdBind
+       proxyNetwork string       // network between a proxy server and a client
+       proxyAddress string       // proxy server address
+
+       // ProxyDial specifies the optional dial function for
+       // establishing the transport connection.
+       ProxyDial func(context.Context, string, string) (net.Conn, error)
+
+       // AuthMethods specifies the list of request authention
+       // methods.
+       // If empty, SOCKS client requests only AuthMethodNotRequired.
+       AuthMethods []socksAuthMethod
+
+       // Authenticate specifies the optional authentication
+       // function. It must be non-nil when AuthMethods is not empty.
+       // It must return an error when the authentication is failed.
+       Authenticate func(context.Context, io.ReadWriter, socksAuthMethod) error
+}
+
+// DialContext connects to the provided address on the provided
+// network.
+//
+// The returned error value may be a net.OpError. When the Op field of
+// net.OpError contains "socks", the Source field contains a proxy
+// server address and the Addr field contains a command target
+// address.
+//
+// See func Dial of the net package of standard library for a
+// description of the network and address parameters.
+func (d *socksDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
+       switch network {
+       case "tcp", "tcp6", "tcp4":
+       default:
+               proxy, dst, _ := d.pathAddrs(address)
+               return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("network not implemented")}
+       }
+       switch d.cmd {
+       case socksCmdConnect, sockscmdBind:
+       default:
+               proxy, dst, _ := d.pathAddrs(address)
+               return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("command not implemented")}
+       }
+       if ctx == nil {
+               ctx = context.Background()
+       }
+       var err error
+       var c net.Conn
+       if d.ProxyDial != nil {
+               c, err = d.ProxyDial(ctx, d.proxyNetwork, d.proxyAddress)
+       } else {
+               var dd net.Dialer
+               c, err = dd.DialContext(ctx, d.proxyNetwork, d.proxyAddress)
+       }
+       if err != nil {
+               proxy, dst, _ := d.pathAddrs(address)
+               return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
+       }
+       a, err := d.connect(ctx, c, address)
+       if err != nil {
+               c.Close()
+               proxy, dst, _ := d.pathAddrs(address)
+               return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
+       }
+       return &socksConn{Conn: c, boundAddr: a}, nil
+}
+
+// Dial connects to the provided address on the provided network.
+//
+// Deprecated: Use DialContext instead.
+func (d *socksDialer) Dial(network, address string) (net.Conn, error) {
+       return d.DialContext(context.Background(), network, address)
+}
+
+func (d *socksDialer) pathAddrs(address string) (proxy, dst net.Addr, err error) {
+       for i, s := range []string{d.proxyAddress, address} {
+               host, port, err := sockssplitHostPort(s)
+               if err != nil {
+                       return nil, nil, err
+               }
+               a := &socksAddr{Port: port}
+               a.IP = net.ParseIP(host)
+               if a.IP == nil {
+                       a.Name = host
+               }
+               if i == 0 {
+                       proxy = a
+               } else {
+                       dst = a
+               }
+       }
+       return
+}
+
+// NewDialer returns a new Dialer that dials through the provided
+// proxy server's network and address.
+func socksNewDialer(network, address string) *socksDialer {
+       return &socksDialer{proxyNetwork: network, proxyAddress: address, cmd: socksCmdConnect}
+}
+
+const (
+       socksauthUsernamePasswordVersion = 0x01
+       socksauthStatusSucceeded         = 0x00
+)
+
+// UsernamePassword are the credentials for the username/password
+// authentication method.
+type socksUsernamePassword struct {
+       Username string
+       Password string
+}
+
+// Authenticate authenticates a pair of username and password with the
+// proxy server.
+func (up *socksUsernamePassword) Authenticate(ctx context.Context, rw io.ReadWriter, auth socksAuthMethod) error {
+       switch auth {
+       case socksAuthMethodNotRequired:
+               return nil
+       case socksAuthMethodUsernamePassword:
+               if len(up.Username) == 0 || len(up.Username) > 255 || len(up.Password) == 0 || len(up.Password) > 255 {
+                       return errors.New("invalid username/password")
+               }
+               b := []byte{socksauthUsernamePasswordVersion}
+               b = append(b, byte(len(up.Username)))
+               b = append(b, up.Username...)
+               b = append(b, byte(len(up.Password)))
+               b = append(b, up.Password...)
+               // TODO(mikio): handle IO deadlines and cancelation if
+               // necessary
+               if _, err := rw.Write(b); err != nil {
+                       return err
+               }
+               if _, err := io.ReadFull(rw, b[:2]); err != nil {
+                       return err
+               }
+               if b[0] != socksauthUsernamePasswordVersion {
+                       return errors.New("invalid username/password version")
+               }
+               if b[1] != socksauthStatusSucceeded {
+                       return errors.New("username/password authentication failed")
+               }
+               return nil
+       }
+       return errors.New("unsupported authentication method " + strconv.Itoa(int(auth)))
+}
index dbfef80ff0098eadd1697d3a0b96004812b64e42..b19f7ce8ed0178c48f0cd62b5f6ccabb64a4adf3 100644 (file)
@@ -29,7 +29,6 @@ import (
        "time"
 
        "golang_org/x/net/lex/httplex"
-       "golang_org/x/net/proxy"
 )
 
 // DefaultTransport is the default implementation of Transport and is
@@ -1013,23 +1012,6 @@ func (t *Transport) getConn(treq *transportRequest, cm connectMethod) (*persistC
        }
 }
 
-type oneConnDialer <-chan net.Conn
-
-func newOneConnDialer(c net.Conn) proxy.Dialer {
-       ch := make(chan net.Conn, 1)
-       ch <- c
-       return oneConnDialer(ch)
-}
-
-func (d oneConnDialer) Dial(network, addr string) (net.Conn, error) {
-       select {
-       case c := <-d:
-               return c, nil
-       default:
-               return nil, io.EOF
-       }
-}
-
 // The connect method and the transport can both specify a TLS
 // Host name.  The transport's name takes precedence if present.
 func chooseTLSHost(cm connectMethod, t *Transport) string {
@@ -1156,18 +1138,22 @@ func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (*persistCon
                // Do nothing. Not using a proxy.
        case cm.proxyURL.Scheme == "socks5":
                conn := pconn.conn
-               var auth *proxy.Auth
+               d := socksNewDialer("tcp", conn.RemoteAddr().String())
+               d.ProxyDial = func(_ context.Context, _, _ string) (net.Conn, error) {
+                       return conn, nil
+               }
                if u := cm.proxyURL.User; u != nil {
-                       auth = &proxy.Auth{}
-                       auth.User = u.Username()
+                       auth := &socksUsernamePassword{
+                               Username: u.Username(),
+                       }
                        auth.Password, _ = u.Password()
+                       d.AuthMethods = []socksAuthMethod{
+                               socksAuthMethodNotRequired,
+                               socksAuthMethodUsernamePassword,
+                       }
+                       d.Authenticate = auth.Authenticate
                }
-               p, err := proxy.SOCKS5("", cm.addr(), auth, newOneConnDialer(conn))
-               if err != nil {
-                       conn.Close()
-                       return nil, err
-               }
-               if _, err := p.Dial("tcp", cm.targetAddr); err != nil {
+               if _, err := d.DialContext(ctx, "tcp", cm.targetAddr); err != nil {
                        conn.Close()
                        return nil, err
                }
index f69d71abf6daac31c0dbb87a8e8c19d9e87e8332..a48e61e9ba1e908e642e4b356205cd8d98f1c75a 100644 (file)
@@ -959,7 +959,7 @@ func TestTransportExpect100Continue(t *testing.T) {
        }
 }
 
-func TestSocks5Proxy(t *testing.T) {
+func TestSOCKS5Proxy(t *testing.T) {
        defer afterTest(t)
        ch := make(chan string, 1)
        l := newLocalListener(t)
@@ -996,9 +996,9 @@ func TestSocks5Proxy(t *testing.T) {
                var ipLen int
                switch buf[3] {
                case 1:
-                       ipLen = 4
+                       ipLen = net.IPv4len
                case 4:
-                       ipLen = 16
+                       ipLen = net.IPv6len
                default:
                        t.Errorf("socks5 proxy second read: unexpected address type %v", buf[4])
                        return
diff --git a/src/vendor/golang_org/x/net/proxy/direct.go b/src/vendor/golang_org/x/net/proxy/direct.go
deleted file mode 100644 (file)
index 4c5ad88..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// 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
-
-import (
-       "net"
-)
-
-type direct struct{}
-
-// Direct is a direct proxy: one that makes network connections directly.
-var Direct = direct{}
-
-func (direct) Dial(network, addr string) (net.Conn, error) {
-       return net.Dial(network, addr)
-}
diff --git a/src/vendor/golang_org/x/net/proxy/per_host.go b/src/vendor/golang_org/x/net/proxy/per_host.go
deleted file mode 100644 (file)
index f540b19..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-// 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
-
-import (
-       "net"
-       "strings"
-)
-
-// A PerHost directs connections to a default Dialer unless the hostname
-// requested matches one of a number of exceptions.
-type PerHost struct {
-       def, bypass Dialer
-
-       bypassNetworks []*net.IPNet
-       bypassIPs      []net.IP
-       bypassZones    []string
-       bypassHosts    []string
-}
-
-// NewPerHost returns a PerHost Dialer that directs connections to either
-// defaultDialer or bypass, depending on whether the connection matches one of
-// the configured rules.
-func NewPerHost(defaultDialer, bypass Dialer) *PerHost {
-       return &PerHost{
-               def:    defaultDialer,
-               bypass: bypass,
-       }
-}
-
-// Dial connects to the address addr on the given network through either
-// defaultDialer or bypass.
-func (p *PerHost) Dial(network, addr string) (c net.Conn, err error) {
-       host, _, err := net.SplitHostPort(addr)
-       if err != nil {
-               return nil, err
-       }
-
-       return p.dialerForRequest(host).Dial(network, addr)
-}
-
-func (p *PerHost) dialerForRequest(host string) Dialer {
-       if ip := net.ParseIP(host); ip != nil {
-               for _, net := range p.bypassNetworks {
-                       if net.Contains(ip) {
-                               return p.bypass
-                       }
-               }
-               for _, bypassIP := range p.bypassIPs {
-                       if bypassIP.Equal(ip) {
-                               return p.bypass
-                       }
-               }
-               return p.def
-       }
-
-       for _, zone := range p.bypassZones {
-               if strings.HasSuffix(host, zone) {
-                       return p.bypass
-               }
-               if host == zone[1:] {
-                       // For a zone "example.com", we match "example.com"
-                       // too.
-                       return p.bypass
-               }
-       }
-       for _, bypassHost := range p.bypassHosts {
-               if bypassHost == host {
-                       return p.bypass
-               }
-       }
-       return p.def
-}
-
-// AddFromString parses a string that contains comma-separated values
-// specifying hosts that should use the bypass proxy. Each value is either an
-// IP address, a CIDR range, a zone (*.example.com) or a hostname
-// (localhost). A best effort is made to parse the string and errors are
-// ignored.
-func (p *PerHost) AddFromString(s string) {
-       hosts := strings.Split(s, ",")
-       for _, host := range hosts {
-               host = strings.TrimSpace(host)
-               if len(host) == 0 {
-                       continue
-               }
-               if strings.Contains(host, "/") {
-                       // We assume that it's a CIDR address like 127.0.0.0/8
-                       if _, net, err := net.ParseCIDR(host); err == nil {
-                               p.AddNetwork(net)
-                       }
-                       continue
-               }
-               if ip := net.ParseIP(host); ip != nil {
-                       p.AddIP(ip)
-                       continue
-               }
-               if strings.HasPrefix(host, "*.") {
-                       p.AddZone(host[1:])
-                       continue
-               }
-               p.AddHost(host)
-       }
-}
-
-// AddIP specifies an IP address that will use the bypass proxy. Note that
-// this will only take effect if a literal IP address is dialed. A connection
-// to a named host will never match an IP.
-func (p *PerHost) AddIP(ip net.IP) {
-       p.bypassIPs = append(p.bypassIPs, ip)
-}
-
-// AddNetwork specifies an IP range that will use the bypass proxy. Note that
-// this will only take effect if a literal IP address is dialed. A connection
-// to a named host will never match.
-func (p *PerHost) AddNetwork(net *net.IPNet) {
-       p.bypassNetworks = append(p.bypassNetworks, net)
-}
-
-// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of
-// "example.com" matches "example.com" and all of its subdomains.
-func (p *PerHost) AddZone(zone string) {
-       if strings.HasSuffix(zone, ".") {
-               zone = zone[:len(zone)-1]
-       }
-       if !strings.HasPrefix(zone, ".") {
-               zone = "." + zone
-       }
-       p.bypassZones = append(p.bypassZones, zone)
-}
-
-// AddHost specifies a hostname that will use the bypass proxy.
-func (p *PerHost) AddHost(host string) {
-       if strings.HasSuffix(host, ".") {
-               host = host[:len(host)-1]
-       }
-       p.bypassHosts = append(p.bypassHosts, host)
-}
diff --git a/src/vendor/golang_org/x/net/proxy/per_host_test.go b/src/vendor/golang_org/x/net/proxy/per_host_test.go
deleted file mode 100644 (file)
index a7d8095..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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
-
-import (
-       "errors"
-       "net"
-       "reflect"
-       "testing"
-)
-
-type recordingProxy struct {
-       addrs []string
-}
-
-func (r *recordingProxy) Dial(network, addr string) (net.Conn, error) {
-       r.addrs = append(r.addrs, addr)
-       return nil, errors.New("recordingProxy")
-}
-
-func TestPerHost(t *testing.T) {
-       var def, bypass recordingProxy
-       perHost := NewPerHost(&def, &bypass)
-       perHost.AddFromString("localhost,*.zone,127.0.0.1,10.0.0.1/8,1000::/16")
-
-       expectedDef := []string{
-               "example.com:123",
-               "1.2.3.4:123",
-               "[1001::]:123",
-       }
-       expectedBypass := []string{
-               "localhost:123",
-               "zone:123",
-               "foo.zone:123",
-               "127.0.0.1:123",
-               "10.1.2.3:123",
-               "[1000::]:123",
-       }
-
-       for _, addr := range expectedDef {
-               perHost.Dial("tcp", addr)
-       }
-       for _, addr := range expectedBypass {
-               perHost.Dial("tcp", addr)
-       }
-
-       if !reflect.DeepEqual(expectedDef, def.addrs) {
-               t.Errorf("Hosts which went to the default proxy didn't match. Got %v, want %v", def.addrs, expectedDef)
-       }
-       if !reflect.DeepEqual(expectedBypass, bypass.addrs) {
-               t.Errorf("Hosts which went to the bypass proxy didn't match. Got %v, want %v", bypass.addrs, expectedBypass)
-       }
-}
diff --git a/src/vendor/golang_org/x/net/proxy/proxy.go b/src/vendor/golang_org/x/net/proxy/proxy.go
deleted file mode 100644 (file)
index 78a8b7b..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-// 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 (
-       "errors"
-       "net"
-       "net/url"
-       "os"
-)
-
-// A Dialer is a means to establish a connection.
-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.
-func FromEnvironment() Dialer {
-       allProxy := os.Getenv("all_proxy")
-       if len(allProxy) == 0 {
-               return Direct
-       }
-
-       proxyURL, err := url.Parse(allProxy)
-       if err != nil {
-               return Direct
-       }
-       proxy, err := FromURL(proxyURL, Direct)
-       if err != nil {
-               return Direct
-       }
-
-       noProxy := os.Getenv("no_proxy")
-       if len(noProxy) == 0 {
-               return proxy
-       }
-
-       perHost := NewPerHost(proxy, Direct)
-       perHost.AddFromString(noProxy)
-       return perHost
-}
-
-// 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 RegisterDialerType(scheme string, f func(*url.URL, Dialer) (Dialer, error)) {
-       if proxySchemes == nil {
-               proxySchemes = make(map[string]func(*url.URL, Dialer) (Dialer, error))
-       }
-       proxySchemes[scheme] = f
-}
-
-// FromURL returns a Dialer given a URL specification and an underlying
-// Dialer for it to make network requests.
-func FromURL(u *url.URL, forward Dialer) (Dialer, error) {
-       var auth *Auth
-       if u.User != nil {
-               auth = new(Auth)
-               auth.User = u.User.Username()
-               if p, ok := u.User.Password(); ok {
-                       auth.Password = p
-               }
-       }
-
-       switch u.Scheme {
-       case "socks5":
-               return SOCKS5("tcp", u.Host, auth, forward)
-       }
-
-       // If the scheme doesn't match any of the built-in schemes, see if it
-       // was registered by another package.
-       if proxySchemes != nil {
-               if f, ok := proxySchemes[u.Scheme]; ok {
-                       return f(u, forward)
-               }
-       }
-
-       return nil, errors.New("proxy: unknown scheme: " + u.Scheme)
-}
diff --git a/src/vendor/golang_org/x/net/proxy/proxy_test.go b/src/vendor/golang_org/x/net/proxy/proxy_test.go
deleted file mode 100644 (file)
index c19a5c0..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-// 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
-
-import (
-       "io"
-       "net"
-       "net/url"
-       "strconv"
-       "sync"
-       "testing"
-)
-
-func TestFromURL(t *testing.T) {
-       endSystem, err := net.Listen("tcp", "127.0.0.1:0")
-       if err != nil {
-               t.Fatalf("net.Listen failed: %v", err)
-       }
-       defer endSystem.Close()
-       gateway, err := net.Listen("tcp", "127.0.0.1:0")
-       if err != nil {
-               t.Fatalf("net.Listen failed: %v", err)
-       }
-       defer gateway.Close()
-
-       var wg sync.WaitGroup
-       wg.Add(1)
-       go socks5Gateway(t, gateway, endSystem, socks5Domain, &wg)
-
-       url, err := url.Parse("socks5://user:password@" + gateway.Addr().String())
-       if err != nil {
-               t.Fatalf("url.Parse failed: %v", err)
-       }
-       proxy, err := FromURL(url, Direct)
-       if err != nil {
-               t.Fatalf("FromURL failed: %v", err)
-       }
-       _, port, err := net.SplitHostPort(endSystem.Addr().String())
-       if err != nil {
-               t.Fatalf("net.SplitHostPort failed: %v", err)
-       }
-       if c, err := proxy.Dial("tcp", "localhost:"+port); err != nil {
-               t.Fatalf("FromURL.Dial failed: %v", err)
-       } else {
-               c.Close()
-       }
-
-       wg.Wait()
-}
-
-func TestSOCKS5(t *testing.T) {
-       endSystem, err := net.Listen("tcp", "127.0.0.1:0")
-       if err != nil {
-               t.Fatalf("net.Listen failed: %v", err)
-       }
-       defer endSystem.Close()
-       gateway, err := net.Listen("tcp", "127.0.0.1:0")
-       if err != nil {
-               t.Fatalf("net.Listen failed: %v", err)
-       }
-       defer gateway.Close()
-
-       var wg sync.WaitGroup
-       wg.Add(1)
-       go socks5Gateway(t, gateway, endSystem, socks5IP4, &wg)
-
-       proxy, err := SOCKS5("tcp", gateway.Addr().String(), nil, Direct)
-       if err != nil {
-               t.Fatalf("SOCKS5 failed: %v", err)
-       }
-       if c, err := proxy.Dial("tcp", endSystem.Addr().String()); err != nil {
-               t.Fatalf("SOCKS5.Dial failed: %v", err)
-       } else {
-               c.Close()
-       }
-
-       wg.Wait()
-}
-
-func socks5Gateway(t *testing.T, gateway, endSystem net.Listener, typ byte, wg *sync.WaitGroup) {
-       defer wg.Done()
-
-       c, err := gateway.Accept()
-       if err != nil {
-               t.Errorf("net.Listener.Accept failed: %v", err)
-               return
-       }
-       defer c.Close()
-
-       b := make([]byte, 32)
-       var n int
-       if typ == socks5Domain {
-               n = 4
-       } else {
-               n = 3
-       }
-       if _, err := io.ReadFull(c, b[:n]); err != nil {
-               t.Errorf("io.ReadFull failed: %v", err)
-               return
-       }
-       if _, err := c.Write([]byte{socks5Version, socks5AuthNone}); err != nil {
-               t.Errorf("net.Conn.Write failed: %v", err)
-               return
-       }
-       if typ == socks5Domain {
-               n = 16
-       } else {
-               n = 10
-       }
-       if _, err := io.ReadFull(c, b[:n]); err != nil {
-               t.Errorf("io.ReadFull failed: %v", err)
-               return
-       }
-       if b[0] != socks5Version || b[1] != socks5Connect || b[2] != 0x00 || b[3] != typ {
-               t.Errorf("got an unexpected packet: %#02x %#02x %#02x %#02x", b[0], b[1], b[2], b[3])
-               return
-       }
-       if typ == socks5Domain {
-               copy(b[:5], []byte{socks5Version, 0x00, 0x00, socks5Domain, 9})
-               b = append(b, []byte("localhost")...)
-       } else {
-               copy(b[:4], []byte{socks5Version, 0x00, 0x00, socks5IP4})
-       }
-       host, port, err := net.SplitHostPort(endSystem.Addr().String())
-       if err != nil {
-               t.Errorf("net.SplitHostPort failed: %v", err)
-               return
-       }
-       b = append(b, []byte(net.ParseIP(host).To4())...)
-       p, err := strconv.Atoi(port)
-       if err != nil {
-               t.Errorf("strconv.Atoi failed: %v", err)
-               return
-       }
-       b = append(b, []byte{byte(p >> 8), byte(p)}...)
-       if _, err := c.Write(b); err != nil {
-               t.Errorf("net.Conn.Write failed: %v", err)
-               return
-       }
-}
diff --git a/src/vendor/golang_org/x/net/proxy/socks5.go b/src/vendor/golang_org/x/net/proxy/socks5.go
deleted file mode 100644 (file)
index 973f57f..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-// 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
-
-import (
-       "errors"
-       "io"
-       "net"
-       "strconv"
-)
-
-// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given address
-// with an optional username and password. See RFC 1928.
-func SOCKS5(network, addr string, auth *Auth, forward Dialer) (Dialer, error) {
-       s := &socks5{
-               network: network,
-               addr:    addr,
-               forward: forward,
-       }
-       if auth != nil {
-               s.user = auth.User
-               s.password = auth.Password
-       }
-
-       return s, nil
-}
-
-type socks5 struct {
-       user, password string
-       network, addr  string
-       forward        Dialer
-}
-
-const socks5Version = 5
-
-const (
-       socks5AuthNone     = 0
-       socks5AuthPassword = 2
-)
-
-const socks5Connect = 1
-
-const (
-       socks5IP4    = 1
-       socks5Domain = 3
-       socks5IP6    = 4
-)
-
-var socks5Errors = []string{
-       "",
-       "general failure",
-       "connection forbidden",
-       "network unreachable",
-       "host unreachable",
-       "connection refused",
-       "TTL expired",
-       "command not supported",
-       "address type not supported",
-}
-
-// Dial connects to the address addr on the network net via the SOCKS5 proxy.
-func (s *socks5) Dial(network, addr string) (net.Conn, error) {
-       switch network {
-       case "tcp", "tcp6", "tcp4":
-       default:
-               return nil, errors.New("proxy: no support for SOCKS5 proxy connections of type " + network)
-       }
-
-       conn, err := s.forward.Dial(s.network, s.addr)
-       if err != nil {
-               return nil, err
-       }
-       if err := s.connect(conn, addr); err != nil {
-               conn.Close()
-               return nil, err
-       }
-       return conn, nil
-}
-
-// connect takes an existing connection to a socks5 proxy server,
-// and commands the server to extend that connection to target,
-// which must be a canonical address with a host and port.
-func (s *socks5) connect(conn net.Conn, target string) error {
-       host, portStr, err := net.SplitHostPort(target)
-       if err != nil {
-               return err
-       }
-
-       port, err := strconv.Atoi(portStr)
-       if err != nil {
-               return errors.New("proxy: failed to parse port number: " + portStr)
-       }
-       if port < 1 || port > 0xffff {
-               return errors.New("proxy: port number out of range: " + portStr)
-       }
-
-       // the size here is just an estimate
-       buf := make([]byte, 0, 6+len(host))
-
-       buf = append(buf, socks5Version)
-       if len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 {
-               buf = append(buf, 2 /* num auth methods */, socks5AuthNone, socks5AuthPassword)
-       } else {
-               buf = append(buf, 1 /* num auth methods */, socks5AuthNone)
-       }
-
-       if _, err := conn.Write(buf); err != nil {
-               return errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error())
-       }
-
-       if _, err := io.ReadFull(conn, buf[:2]); err != nil {
-               return errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error())
-       }
-       if buf[0] != 5 {
-               return errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0])))
-       }
-       if buf[1] == 0xff {
-               return errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication")
-       }
-
-       if buf[1] == socks5AuthPassword {
-               buf = buf[:0]
-               buf = append(buf, 1 /* password protocol version */)
-               buf = append(buf, uint8(len(s.user)))
-               buf = append(buf, s.user...)
-               buf = append(buf, uint8(len(s.password)))
-               buf = append(buf, s.password...)
-
-               if _, err := conn.Write(buf); err != nil {
-                       return errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error())
-               }
-
-               if _, err := io.ReadFull(conn, buf[:2]); err != nil {
-                       return errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error())
-               }
-
-               if buf[1] != 0 {
-                       return errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password")
-               }
-       }
-
-       buf = buf[:0]
-       buf = append(buf, socks5Version, socks5Connect, 0 /* reserved */)
-
-       if ip := net.ParseIP(host); ip != nil {
-               if ip4 := ip.To4(); ip4 != nil {
-                       buf = append(buf, socks5IP4)
-                       ip = ip4
-               } else {
-                       buf = append(buf, socks5IP6)
-               }
-               buf = append(buf, ip...)
-       } else {
-               if len(host) > 255 {
-                       return errors.New("proxy: destination hostname too long: " + host)
-               }
-               buf = append(buf, socks5Domain)
-               buf = append(buf, byte(len(host)))
-               buf = append(buf, host...)
-       }
-       buf = append(buf, byte(port>>8), byte(port))
-
-       if _, err := conn.Write(buf); err != nil {
-               return errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error())
-       }
-
-       if _, err := io.ReadFull(conn, buf[:4]); err != nil {
-               return errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error())
-       }
-
-       failure := "unknown error"
-       if int(buf[1]) < len(socks5Errors) {
-               failure = socks5Errors[buf[1]]
-       }
-
-       if len(failure) > 0 {
-               return errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure)
-       }
-
-       bytesToDiscard := 0
-       switch buf[3] {
-       case socks5IP4:
-               bytesToDiscard = net.IPv4len
-       case socks5IP6:
-               bytesToDiscard = net.IPv6len
-       case socks5Domain:
-               _, err := io.ReadFull(conn, buf[:1])
-               if err != nil {
-                       return errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error())
-               }
-               bytesToDiscard = int(buf[0])
-       default:
-               return errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr)
-       }
-
-       if cap(buf) < bytesToDiscard {
-               buf = make([]byte, bytesToDiscard)
-       } else {
-               buf = buf[:bytesToDiscard]
-       }
-       if _, err := io.ReadFull(conn, buf); err != nil {
-               return errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error())
-       }
-
-       // Also need to discard the port number
-       if _, err := io.ReadFull(conn, buf[:2]); err != nil {
-               return errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error())
-       }
-
-       return nil
-}