Project

General

Profile

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

Patch 2 without default of p_addr = :ENV - drbrain (Eric Hodel), 06/13/2012 06:36 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
  # can create a proxy from the +HTTP_PROXY+ environment variable if +:ENV+ is
273
  # used for the proxy address:
274
  #
275
  #   Net::HTTP::Proxy(:ENV).start('www.example.com') { |http|
276
  #     # connect with ENV['HTTP_PROXY'] if available
277
  #   end
278
  #
279
  # Net::HTTP will be returned when no proxy is configured so there is no need
280
  # for conditional code.
281
  #
282
  # You may also create a custom proxy:
272 283
  #
273 284
  #   proxy_addr = 'your.proxy.host'
274 285
  #   proxy_port = 8080
......
277 288
  #     # always connect to your.proxy.addr:8080
278 289
  #   }
279 290
  #
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 291
  # See Net::HTTP::Proxy for further details and examples such as proxies that
284 292
  # require a username and password.
285 293
  #
......
878 886
    # Creates an HTTP proxy class which behaves like Net::HTTP, but
879 887
    # performs all access via the specified proxy.
880 888
    #
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.
889
    # If +:ENV+ is given for +p_addr+, the proxy host and port are taken from
890
    # the +HTTP_PROXY+ environment variable (or its lowercase equivalent) if
891
    # present.  If the proxy requires authentication you must supply it by
892
    # hand.
893
    #
894
    # If you are connecting to a custom proxy, the arguments are the DNS name
895
    # or IP address of the proxy host, the port to use to access the proxy,
896
    # and a username and password if authorization is required to use the
897
    # proxy.
898
    #
899
    # If +p_addr+ is nil, this method returns self (a Net::HTTP object).
884 900
    #
885 901
    # You can replace any use of the Net::HTTP class with use of the
886 902
    # proxy class created.
887 903
    #
888
    # If +p_addr+ is nil, this method returns self (a Net::HTTP object).
889
    #
890 904
    #   # Example
891 905
    #   proxy_class = Net::HTTP::Proxy('proxy.example.com', 8080)
892 906
    #
......
907 921
    #     # and password
908 922
    #   }
909 923
    #
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)
924
    def HTTP.Proxy(p_addr = nil, p_port = nil, p_user = nil, p_pass = nil)
914 925
      return self unless p_addr
915
      delta = ProxyDelta
916
      proxyclass = Class.new(self)
917
      proxyclass.module_eval {
918
        include delta
926

  
927
      if p_addr == :ENV then
928
        env_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY']
929

  
930
        return self unless env_proxy
931

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

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

  
929 948
    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