proxy.go 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. // Package proxy provides support for a variety of protocols to proxy network
  5. // data.
  6. package proxy // import "golang.org/x/net/proxy"
  7. import (
  8. "errors"
  9. "net"
  10. "net/url"
  11. "os"
  12. )
  13. // A Dialer is a means to establish a connection.
  14. type Dialer interface {
  15. // Dial connects to the given address via the proxy.
  16. Dial(network, addr string) (c net.Conn, err error)
  17. }
  18. // Auth contains authentication parameters that specific Dialers may require.
  19. type Auth struct {
  20. User, Password string
  21. }
  22. // FromEnvironment returns the dialer specified by the proxy related variables in
  23. // the environment.
  24. func FromEnvironment() Dialer {
  25. allProxy := os.Getenv("all_proxy")
  26. if len(allProxy) == 0 {
  27. return Direct
  28. }
  29. proxyURL, err := url.Parse(allProxy)
  30. if err != nil {
  31. return Direct
  32. }
  33. proxy, err := FromURL(proxyURL, Direct)
  34. if err != nil {
  35. return Direct
  36. }
  37. noProxy := os.Getenv("no_proxy")
  38. if len(noProxy) == 0 {
  39. return proxy
  40. }
  41. perHost := NewPerHost(proxy, Direct)
  42. perHost.AddFromString(noProxy)
  43. return perHost
  44. }
  45. // proxySchemes is a map from URL schemes to a function that creates a Dialer
  46. // from a URL with such a scheme.
  47. var proxySchemes map[string]func(*url.URL, Dialer) (Dialer, error)
  48. // RegisterDialerType takes a URL scheme and a function to generate Dialers from
  49. // a URL with that scheme and a forwarding Dialer. Registered schemes are used
  50. // by FromURL.
  51. func RegisterDialerType(scheme string, f func(*url.URL, Dialer) (Dialer, error)) {
  52. if proxySchemes == nil {
  53. proxySchemes = make(map[string]func(*url.URL, Dialer) (Dialer, error))
  54. }
  55. proxySchemes[scheme] = f
  56. }
  57. // FromURL returns a Dialer given a URL specification and an underlying
  58. // Dialer for it to make network requests.
  59. func FromURL(u *url.URL, forward Dialer) (Dialer, error) {
  60. var auth *Auth
  61. if u.User != nil {
  62. auth = new(Auth)
  63. auth.User = u.User.Username()
  64. if p, ok := u.User.Password(); ok {
  65. auth.Password = p
  66. }
  67. }
  68. switch u.Scheme {
  69. case "socks5":
  70. return SOCKS5("tcp", u.Host, auth, forward)
  71. }
  72. // If the scheme doesn't match any of the built-in schemes, see if it
  73. // was registered by another package.
  74. if proxySchemes != nil {
  75. if f, ok := proxySchemes[u.Scheme]; ok {
  76. return f(u, forward)
  77. }
  78. }
  79. return nil, errors.New("proxy: unknown scheme: " + u.Scheme)
  80. }