Project

General

Profile

Feature #6546 ยป net.http.proxy_from_env.2.patch

drbrain (Eric Hodel), 06/12/2012 09:17 AM

View differences:

lib/net/http.rb (working copy)
268 268
  # === Proxies
269 269
  #
270 270
  # Net::HTTP::Proxy has the same methods as Net::HTTP but its instances always
271
  # connect via the proxy instead of directly to the given host.
271
  # connect via the proxy instead of directly to the given host.  Net::HTTP
272
  # will automatically create a proxy from the +HTTP_PROXY+ environment
273
  # variable if it is present.  To disable use of +HTTP_PROXY+, pass +nil+ for
274
  # the proxy address.  Net::HTTP will be returned when no proxy is configured
275
  # so there is no need for conditional code.
276
  #
277
  # You may also create a custom proxy:
272 278
  #
273 279
  #   proxy_addr = 'your.proxy.host'
274 280
  #   proxy_port = 8080
......
277 283
  #     # always connect to your.proxy.addr:8080
278 284
  #   }
279 285
  #
280
  # Net::HTTP::Proxy returns a Net::HTTP instance when proxy_addr is nil so
281
  # there is no need for conditional code.
282
  #
283 286
  # See Net::HTTP::Proxy for further details and examples such as proxies that
284 287
  # require a username and password.
285 288
  #
......
571 574
    # HTTP session.
572 575
    # The +address+ should be a DNS hostname or IP address.
573 576
    # If +p_addr+ is given, creates a Net::HTTP object with proxy support.
574
    def HTTP.new(address, port = nil, p_addr = nil, p_port = nil, p_user = nil, p_pass = nil)
577
    def HTTP.new(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil)
575 578
      Proxy(p_addr, p_port, p_user, p_pass).newobj(address, port)
576 579
    end
577 580

  
......
878 881
    # Creates an HTTP proxy class which behaves like Net::HTTP, but
879 882
    # performs all access via the specified proxy.
880 883
    #
881
    # The arguments are the DNS name or IP address of the proxy host,
882
    # the port to use to access the proxy, and a username and password
883
    # if authorization is required to use the proxy.
884
    # If no arguments are given, the proxy host and port are taken from the
885
    # +HTTP_PROXY+ environment variable (or its lowercase equivalent) if
886
    # present.  If the proxy requires authentication you must supply it by
887
    # hand.
888
    #
889
    # If you are connecting to a custom proxy, the arguments are the DNS name
890
    # or IP address of the proxy host, the port to use to access the proxy,
891
    # and a username and password if authorization is required to use the
892
    # proxy.
893
    #
894
    # If +p_addr+ is nil, this method returns self (a Net::HTTP object).  If
895
    # +p_addr+ is +:ENV+ the proxy is constructed from +HTTP_PROXY+ and +p_addr+
896
    # is determined automatically.  You may use +:ENV+ with +p_user+ and
897
    # +p_pass+ to provide authentication for +HTTP_PROXY+.
884 898
    #
885 899
    # You can replace any use of the Net::HTTP class with use of the
886 900
    # proxy class created.
887 901
    #
888
    # If +p_addr+ is nil, this method returns self (a Net::HTTP object).
889
    #
890 902
    #   # Example
891 903
    #   proxy_class = Net::HTTP::Proxy('proxy.example.com', 8080)
892 904
    #
......
907 919
    #     # and password
908 920
    #   }
909 921
    #
910
    # Note that net/http does not use the HTTP_PROXY environment variable.
911
    # If you want to use a proxy, you must set it explicitly.
912
    #
913
    def HTTP.Proxy(p_addr, p_port = nil, p_user = nil, p_pass = nil)
922
    def HTTP.Proxy(p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil)
914 923
      return self unless p_addr
915
      delta = ProxyDelta
916
      proxyclass = Class.new(self)
917
      proxyclass.module_eval {
918
        include delta
924

  
925
      if p_addr == :ENV then
926
        env_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY']
927

  
928
        return self unless env_proxy
929

  
930
        env_proxy =~ /:([^\]]+)\z/ # handle IPv6 address like [::1]:8000
931
        p_addr = $` || env_proxy
932
        p_port = $1.to_i if $1
933
      end
934

  
935
      Class.new(self) {
936
        include Net::HTTP::ProxyDelta
919 937
        # with proxy
920 938
        @is_proxy_class = true
921 939
        @proxy_address = p_addr
......
923 941
        @proxy_user    = p_user
924 942
        @proxy_pass    = p_pass
925 943
      }
926
      proxyclass
927 944
    end
928 945

  
929 946
    class << HTTP
test/net/http/test_http.rb (working copy)
5 5
require 'stringio'
6 6
require_relative 'utils'
7 7

  
8
class TestNetHTTP < Test::Unit::TestCase
9

  
10
  def test_class_Proxy
11
    no_proxy_class = Net::HTTP.Proxy nil
12

  
13
    assert_equal Net::HTTP, no_proxy_class
14

  
15
    proxy_class = Net::HTTP.Proxy 'proxy.example', 8000, 'user', 'pass'
16

  
17
    refute_equal Net::HTTP, proxy_class
18

  
19
    assert_operator proxy_class, :<, Net::HTTP
20

  
21
    assert_equal 'proxy.example', proxy_class.proxy_address
22
    assert_equal 8000,            proxy_class.proxy_port
23
    assert_equal 'user',          proxy_class.proxy_user
24
    assert_equal 'pass',          proxy_class.proxy_pass
25
  end
26

  
27
  def test_class_Proxy_from_ENV
28
    clean_http_proxy_env do
29
      ENV['HTTP_PROXY']      = 'proxy.example:8000'
30

  
31
      # These are ignored on purpose.  See Bug 4388 and Feature 6546
32
      ENV['HTTP_PROXY_USER'] = 'user'
33
      ENV['HTTP_PROXY_PASS'] = 'pass'
34

  
35
      proxy_class = Net::HTTP.Proxy :ENV
36

  
37
      refute_equal Net::HTTP, proxy_class
38

  
39
      assert_operator proxy_class, :<, Net::HTTP
40

  
41
      assert_equal 'proxy.example', proxy_class.proxy_address
42
      assert_equal 8000,            proxy_class.proxy_port
43
      assert_nil                    proxy_class.proxy_user
44
      assert_nil                    proxy_class.proxy_pass
45
    end
46
  end
47

  
48
  def test_class_Proxy_from_ENV_ipv6
49
    clean_http_proxy_env do
50
      ENV['HTTP_PROXY'] = '[::1]:8000'
51

  
52
      proxy_class = Net::HTTP.Proxy :ENV
53

  
54
      refute_equal Net::HTTP, proxy_class
55

  
56
      assert_operator proxy_class, :<, Net::HTTP
57

  
58
      assert_equal '[::1]', proxy_class.proxy_address
59
      assert_equal 8000,    proxy_class.proxy_port
60
      assert_nil            proxy_class.proxy_user
61
      assert_nil            proxy_class.proxy_pass
62
    end
63
  end
64

  
65
  def test_class_Proxy_from_ENV_lowercase
66
    clean_http_proxy_env do
67
      ENV['http_proxy']      = 'proxy.example:8000'
68

  
69
      # These are ignored on purpose.  See Bug 4388 and Feature 6546
70
      ENV['http_proxy_user'] = 'user'
71
      ENV['http_proxy_pass'] = 'pass'
72

  
73
      proxy_class = Net::HTTP.Proxy :ENV
74

  
75
      refute_equal Net::HTTP, proxy_class
76

  
77
      assert_operator proxy_class, :<, Net::HTTP
78

  
79
      assert_equal 'proxy.example', proxy_class.proxy_address
80
      assert_equal 8000,            proxy_class.proxy_port
81
      assert_nil                    proxy_class.proxy_user
82
      assert_nil                    proxy_class.proxy_pass
83
    end
84
  end
85

  
86
  def test_class_Proxy_from_ENV_none
87
    clean_http_proxy_env do
88
      no_proxy_class = Net::HTTP.Proxy :ENV
89

  
90
      assert_equal Net::HTTP, no_proxy_class
91
    end
92
  end
93

  
94
  def test_class_Proxy_from_ENV_no_port
95
    clean_http_proxy_env do
96
      ENV['HTTP_PROXY'] = 'proxy.example'
97

  
98
      proxy_class = Net::HTTP.Proxy :ENV
99

  
100
      refute_equal Net::HTTP, proxy_class
101

  
102
      assert_operator proxy_class, :<, Net::HTTP
103

  
104
      assert_equal 'proxy.example', proxy_class.proxy_address
105
      assert_equal 80,              proxy_class.proxy_port
106
      assert_nil                    proxy_class.proxy_user
107
      assert_nil                    proxy_class.proxy_pass
108
    end
109
  end
110

  
111
  def clean_http_proxy_env
112
    orig = {
113
      'HTTP_PROXY'      => ENV['HTTP_PROXY'],
114
      'http_proxy'      => ENV['HTTP_PROXY'],
115
      'HTTP_PROXY_USER' => ENV['HTTP_PROXY_USER'],
116
      'http_proxy_user' => ENV['http_proxy_user'],
117
      'HTTP_PROXY_PASS' => ENV['HTTP_PROXY_PASS'],
118
      'http_proxy_pass' => ENV['http_proxy_pass'],
119
    }
120

  
121
    orig.each_key do |key|
122
      ENV.delete key
123
    end
124

  
125
    yield
126
  ensure
127
    orig.each do |key, value|
128
      ENV[key] = value
129
    end
130
  end
131

  
132
end
133

  
8 134
module TestNetHTTP_version_1_1_methods
9 135

  
10 136
  def test_s_get