1 // Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT.
2 //go:generate bundle -o x_net_proxy.go golang.org/x/net/proxy
4 // Package proxy provides support for a variety of protocols to proxy network
21 type proxy_direct struct{}
23 // Direct is a direct proxy: one that makes network connections directly.
24 var proxy_Direct = proxy_direct{}
26 func (proxy_direct) Dial(network, addr string) (net.Conn, error) {
27 return net.Dial(network, addr)
30 // A PerHost directs connections to a default Dialer unless the host name
31 // requested matches one of a number of exceptions.
32 type proxy_PerHost struct {
33 def, bypass proxy_Dialer
35 bypassNetworks []*net.IPNet
41 // NewPerHost returns a PerHost Dialer that directs connections to either
42 // defaultDialer or bypass, depending on whether the connection matches one of
43 // the configured rules.
44 func proxy_NewPerHost(defaultDialer, bypass proxy_Dialer) *proxy_PerHost {
45 return &proxy_PerHost{
51 // Dial connects to the address addr on the given network through either
52 // defaultDialer or bypass.
53 func (p *proxy_PerHost) Dial(network, addr string) (c net.Conn, err error) {
54 host, _, err := net.SplitHostPort(addr)
59 return p.dialerForRequest(host).Dial(network, addr)
62 func (p *proxy_PerHost) dialerForRequest(host string) proxy_Dialer {
63 if ip := net.ParseIP(host); ip != nil {
64 for _, net := range p.bypassNetworks {
69 for _, bypassIP := range p.bypassIPs {
70 if bypassIP.Equal(ip) {
77 for _, zone := range p.bypassZones {
78 if strings.HasSuffix(host, zone) {
82 // For a zone ".example.com", we match "example.com"
87 for _, bypassHost := range p.bypassHosts {
88 if bypassHost == host {
95 // AddFromString parses a string that contains comma-separated values
96 // specifying hosts that should use the bypass proxy. Each value is either an
97 // IP address, a CIDR range, a zone (*.example.com) or a host name
98 // (localhost). A best effort is made to parse the string and errors are
100 func (p *proxy_PerHost) AddFromString(s string) {
101 hosts := strings.Split(s, ",")
102 for _, host := range hosts {
103 host = strings.TrimSpace(host)
107 if strings.Contains(host, "/") {
108 // We assume that it's a CIDR address like 127.0.0.0/8
109 if _, net, err := net.ParseCIDR(host); err == nil {
114 if ip := net.ParseIP(host); ip != nil {
118 if strings.HasPrefix(host, "*.") {
126 // AddIP specifies an IP address that will use the bypass proxy. Note that
127 // this will only take effect if a literal IP address is dialed. A connection
128 // to a named host will never match an IP.
129 func (p *proxy_PerHost) AddIP(ip net.IP) {
130 p.bypassIPs = append(p.bypassIPs, ip)
133 // AddNetwork specifies an IP range that will use the bypass proxy. Note that
134 // this will only take effect if a literal IP address is dialed. A connection
135 // to a named host will never match.
136 func (p *proxy_PerHost) AddNetwork(net *net.IPNet) {
137 p.bypassNetworks = append(p.bypassNetworks, net)
140 // AddZone specifies a DNS suffix that will use the bypass proxy. A zone of
141 // "example.com" matches "example.com" and all of its subdomains.
142 func (p *proxy_PerHost) AddZone(zone string) {
143 if strings.HasSuffix(zone, ".") {
144 zone = zone[:len(zone)-1]
146 if !strings.HasPrefix(zone, ".") {
149 p.bypassZones = append(p.bypassZones, zone)
152 // AddHost specifies a host name that will use the bypass proxy.
153 func (p *proxy_PerHost) AddHost(host string) {
154 if strings.HasSuffix(host, ".") {
155 host = host[:len(host)-1]
157 p.bypassHosts = append(p.bypassHosts, host)
160 // A Dialer is a means to establish a connection.
161 type proxy_Dialer interface {
162 // Dial connects to the given address via the proxy.
163 Dial(network, addr string) (c net.Conn, err error)
166 // Auth contains authentication parameters that specific Dialers may require.
167 type proxy_Auth struct {
168 User, Password string
171 // FromEnvironment returns the dialer specified by the proxy related variables in
173 func proxy_FromEnvironment() proxy_Dialer {
174 allProxy := proxy_allProxyEnv.Get()
175 if len(allProxy) == 0 {
179 proxyURL, err := url.Parse(allProxy)
183 proxy, err := proxy_FromURL(proxyURL, proxy_Direct)
188 noProxy := proxy_noProxyEnv.Get()
189 if len(noProxy) == 0 {
193 perHost := proxy_NewPerHost(proxy, proxy_Direct)
194 perHost.AddFromString(noProxy)
198 // proxySchemes is a map from URL schemes to a function that creates a Dialer
199 // from a URL with such a scheme.
200 var proxy_proxySchemes map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error)
202 // RegisterDialerType takes a URL scheme and a function to generate Dialers from
203 // a URL with that scheme and a forwarding Dialer. Registered schemes are used
205 func proxy_RegisterDialerType(scheme string, f func(*url.URL, proxy_Dialer) (proxy_Dialer, error)) {
206 if proxy_proxySchemes == nil {
207 proxy_proxySchemes = make(map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error))
209 proxy_proxySchemes[scheme] = f
212 // FromURL returns a Dialer given a URL specification and an underlying
213 // Dialer for it to make network requests.
214 func proxy_FromURL(u *url.URL, forward proxy_Dialer) (proxy_Dialer, error) {
217 auth = new(proxy_Auth)
218 auth.User = u.User.Username()
219 if p, ok := u.User.Password(); ok {
226 return proxy_SOCKS5("tcp", u.Host, auth, forward)
229 // If the scheme doesn't match any of the built-in schemes, see if it
230 // was registered by another package.
231 if proxy_proxySchemes != nil {
232 if f, ok := proxy_proxySchemes[u.Scheme]; ok {
237 return nil, errors.New("proxy: unknown scheme: " + u.Scheme)
241 proxy_allProxyEnv = &proxy_envOnce{
242 names: []string{"ALL_PROXY", "all_proxy"},
244 proxy_noProxyEnv = &proxy_envOnce{
245 names: []string{"NO_PROXY", "no_proxy"},
249 // envOnce looks up an environment variable (optionally by multiple
250 // names) once. It mitigates expensive lookups on some platforms
252 // (Borrowed from net/http/transport.go)
253 type proxy_envOnce struct {
259 func (e *proxy_envOnce) Get() string {
264 func (e *proxy_envOnce) init() {
265 for _, n := range e.names {
273 // SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given address
274 // with an optional username and password. See RFC 1928 and RFC 1929.
275 func proxy_SOCKS5(network, addr string, auth *proxy_Auth, forward proxy_Dialer) (proxy_Dialer, error) {
283 s.password = auth.Password
289 type proxy_socks5 struct {
290 user, password string
295 const proxy_socks5Version = 5
298 proxy_socks5AuthNone = 0
299 proxy_socks5AuthPassword = 2
302 const proxy_socks5Connect = 1
306 proxy_socks5Domain = 3
310 var proxy_socks5Errors = []string{
313 "connection forbidden",
314 "network unreachable",
316 "connection refused",
318 "command not supported",
319 "address type not supported",
322 // Dial connects to the address addr on the given network via the SOCKS5 proxy.
323 func (s *proxy_socks5) Dial(network, addr string) (net.Conn, error) {
325 case "tcp", "tcp6", "tcp4":
327 return nil, errors.New("proxy: no support for SOCKS5 proxy connections of type " + network)
330 conn, err := s.forward.Dial(s.network, s.addr)
334 if err := s.connect(conn, addr); err != nil {
341 // connect takes an existing connection to a socks5 proxy server,
342 // and commands the server to extend that connection to target,
343 // which must be a canonical address with a host and port.
344 func (s *proxy_socks5) connect(conn net.Conn, target string) error {
345 host, portStr, err := net.SplitHostPort(target)
350 port, err := strconv.Atoi(portStr)
352 return errors.New("proxy: failed to parse port number: " + portStr)
354 if port < 1 || port > 0xffff {
355 return errors.New("proxy: port number out of range: " + portStr)
358 // the size here is just an estimate
359 buf := make([]byte, 0, 6+len(host))
361 buf = append(buf, proxy_socks5Version)
362 if len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 {
363 buf = append(buf, 2 /* num auth methods */, proxy_socks5AuthNone, proxy_socks5AuthPassword)
365 buf = append(buf, 1 /* num auth methods */, proxy_socks5AuthNone)
368 if _, err := conn.Write(buf); err != nil {
369 return errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error())
372 if _, err := io.ReadFull(conn, buf[:2]); err != nil {
373 return errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error())
376 return errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0])))
379 return errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication")
383 if buf[1] == proxy_socks5AuthPassword {
385 buf = append(buf, 1 /* password protocol version */)
386 buf = append(buf, uint8(len(s.user)))
387 buf = append(buf, s.user...)
388 buf = append(buf, uint8(len(s.password)))
389 buf = append(buf, s.password...)
391 if _, err := conn.Write(buf); err != nil {
392 return errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error())
395 if _, err := io.ReadFull(conn, buf[:2]); err != nil {
396 return errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error())
400 return errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password")
405 buf = append(buf, proxy_socks5Version, proxy_socks5Connect, 0 /* reserved */)
407 if ip := net.ParseIP(host); ip != nil {
408 if ip4 := ip.To4(); ip4 != nil {
409 buf = append(buf, proxy_socks5IP4)
412 buf = append(buf, proxy_socks5IP6)
414 buf = append(buf, ip...)
417 return errors.New("proxy: destination host name too long: " + host)
419 buf = append(buf, proxy_socks5Domain)
420 buf = append(buf, byte(len(host)))
421 buf = append(buf, host...)
423 buf = append(buf, byte(port>>8), byte(port))
425 if _, err := conn.Write(buf); err != nil {
426 return errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error())
429 if _, err := io.ReadFull(conn, buf[:4]); err != nil {
430 return errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error())
433 failure := "unknown error"
434 if int(buf[1]) < len(proxy_socks5Errors) {
435 failure = proxy_socks5Errors[buf[1]]
438 if len(failure) > 0 {
439 return errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure)
444 case proxy_socks5IP4:
445 bytesToDiscard = net.IPv4len
446 case proxy_socks5IP6:
447 bytesToDiscard = net.IPv6len
448 case proxy_socks5Domain:
449 _, err := io.ReadFull(conn, buf[:1])
451 return errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error())
453 bytesToDiscard = int(buf[0])
455 return errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr)
458 if cap(buf) < bytesToDiscard {
459 buf = make([]byte, bytesToDiscard)
461 buf = buf[:bytesToDiscard]
463 if _, err := io.ReadFull(conn, buf); err != nil {
464 return errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error())
467 // Also need to discard the port number
468 if _, err := io.ReadFull(conn, buf[:2]); err != nil {
469 return errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error())