Skip to content
This repository
Browse code

HTTP proxy support

[#2133 state:committed]

Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
  • Loading branch information...
commit 4d1552810f631898c3d7f758454c92ca35a8cb26 1 parent 5786395
Marshall Huss authored May 18, 2009 jeremy committed August 08, 2009
5  activeresource/CHANGELOG
... ...
@@ -1,3 +1,8 @@
  1
+*Edge*
  2
+
  3
+* HTTP proxy support.  #2133 [Marshall Huss, Sébastien Dabet]
  4
+
  5
+
1 6
 *2.3.2 [Final] (March 15, 2009)*
2 7
 
3 8
 * Nothing new, just included in 2.3.2
22  activeresource/lib/active_resource/base.rb
@@ -257,6 +257,22 @@ def site=(site)
257 257
         end
258 258
       end
259 259
 
  260
+      # Gets the \proxy variable if a proxy is required
  261
+      def proxy
  262
+        # Not using superclass_delegating_reader. See +site+ for explanation
  263
+        if defined?(@proxy)
  264
+          @proxy
  265
+        elsif superclass != Object && superclass.proxy
  266
+          superclass.proxy.dup.freeze
  267
+        end
  268
+      end
  269
+
  270
+      # Sets the URI of the http proxy to the value in the +proxy+ argument.
  271
+      def proxy=(proxy)
  272
+        @connection = nil
  273
+        @proxy = proxy.nil? ? nil : create_proxy_uri_from(proxy)
  274
+      end
  275
+
260 276
       # Gets the \user for REST HTTP authentication.
261 277
       def user
262 278
         # Not using superclass_delegating_reader. See +site+ for explanation
@@ -332,6 +348,7 @@ def timeout
332 348
       def connection(refresh = false)
333 349
         if defined?(@connection) || superclass == Object
334 350
           @connection = Connection.new(site, format) if refresh || @connection.nil?
  351
+          @connection.proxy = proxy if proxy
335 352
           @connection.user = user if user
336 353
           @connection.password = password if password
337 354
           @connection.timeout = timeout if timeout
@@ -622,6 +639,11 @@ def create_site_uri_from(site)
622 639
           site.is_a?(URI) ? site.dup : URI.parse(site)
623 640
         end
624 641
 
  642
+        # Accepts a URI and creates the proxy URI from that.
  643
+        def create_proxy_uri_from(proxy)
  644
+          proxy.is_a?(URI) ? proxy.dup : URI.parse(proxy)
  645
+        end
  646
+
625 647
         # contains a set of the current prefix parameters.
626 648
         def prefix_parameters
627 649
           @prefix_parameters ||= prefix_source.scan(/:\w+/).map { |key| key[1..-1].to_sym }.to_set
16  activeresource/lib/active_resource/connection.rb
@@ -16,7 +16,7 @@ class Connection
16 16
       :delete => 'Accept'
17 17
     }
18 18
 
19  
-    attr_reader :site, :user, :password, :timeout
  19
+    attr_reader :site, :user, :password, :timeout, :proxy
20 20
     attr_accessor :format
21 21
 
22 22
     class << self
@@ -41,6 +41,11 @@ def site=(site)
41 41
       @password = URI.decode(@site.password) if @site.password
42 42
     end
43 43
 
  44
+    # Set the proxy for remote service.
  45
+    def proxy=(proxy)
  46
+      @proxy = proxy.is_a?(URI) ? proxy : URI.parse(proxy)
  47
+    end
  48
+
44 49
     # Sets the user for remote service.
45 50
     def user=(user)
46 51
       @user = user
@@ -132,8 +137,13 @@ def handle_response(response)
132 137
       # Creates new Net::HTTP instance for communication with the
133 138
       # remote service and resources.
134 139
       def http
135  
-        http             = Net::HTTP.new(@site.host, @site.port)
136  
-        http.use_ssl     = @site.is_a?(URI::HTTPS)
  140
+        http =
  141
+          if @proxy
  142
+            Net::HTTP.new(@site.host, @site.port, @proxy.host, @proxy.port, @proxy.user, @proxy.password)
  143
+          else
  144
+            Net::HTTP.new(@site.host, @site.port)
  145
+          end
  146
+        http.use_ssl = @site.is_a?(URI::HTTPS)
137 147
         http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl?
138 148
         http.read_timeout = @timeout if @timeout # If timeout is not set, the default Net::HTTP timeout (60s) is used.
139 149
         http
64  activeresource/test/base_test.rb
@@ -3,6 +3,7 @@
3 3
 require "fixtures/customer"
4 4
 require "fixtures/street_address"
5 5
 require "fixtures/beast"
  6
+require "fixtures/proxy"
6 7
 require 'active_support/core_ext/hash/conversions'
7 8
 
8 9
 class BaseTest < Test::Unit::TestCase
@@ -125,6 +126,28 @@ def test_site_variable_can_be_reset
125 126
     assert_nil actor.site
126 127
   end
127 128
 
  129
+  def test_proxy_accessor_accepts_uri_or_string_argument
  130
+    proxy = URI.parse('http://localhost')
  131
+
  132
+    assert_nothing_raised { Person.proxy = 'http://localhost' }
  133
+    assert_equal proxy, Person.proxy
  134
+
  135
+    assert_nothing_raised { Person.proxy = proxy }
  136
+    assert_equal proxy, Person.proxy
  137
+  end
  138
+
  139
+  def test_should_use_proxy_prefix_and_credentials
  140
+    assert_equal 'http://user:password@proxy.local:3000', ProxyResource.proxy.to_s
  141
+  end
  142
+
  143
+  def test_proxy_variable_can_be_reset
  144
+    actor = Class.new(ActiveResource::Base)
  145
+    assert_nil actor.site
  146
+    actor.proxy = 'http://localhost:31337'
  147
+    actor.proxy = nil
  148
+    assert_nil actor.site
  149
+  end
  150
+
128 151
   def test_should_accept_setting_user
129 152
     Forum.user = 'david'
130 153
     assert_equal('david', Forum.user)
@@ -221,6 +244,47 @@ def test_site_reader_uses_superclass_site_until_written
221 244
     assert_equal fruit.site, apple.site, 'subclass did not adopt changes from parent class'
222 245
   end
223 246
 
  247
+  def test_proxy_reader_uses_superclass_site_until_written
  248
+    # Superclass is Object so returns nil.
  249
+    assert_nil ActiveResource::Base.proxy
  250
+    assert_nil Class.new(ActiveResource::Base).proxy
  251
+
  252
+    # Subclass uses superclass proxy.
  253
+    actor = Class.new(Person)
  254
+    assert_equal Person.proxy, actor.proxy
  255
+
  256
+    # Subclass returns frozen superclass copy.
  257
+    assert !Person.proxy.frozen?
  258
+    assert actor.proxy.frozen?
  259
+
  260
+    # Changing subclass proxy doesn't change superclass site.
  261
+    actor.proxy = 'http://localhost:31337'
  262
+    assert_not_equal Person.proxy, actor.proxy
  263
+
  264
+    # Changed subclass proxy is not frozen.
  265
+    assert !actor.proxy.frozen?
  266
+
  267
+    # Changing superclass proxy doesn't overwrite subclass site.
  268
+    Person.proxy = 'http://somewhere.else'
  269
+    assert_not_equal Person.proxy, actor.proxy
  270
+
  271
+    # Changing superclass proxy after subclassing changes subclass site.
  272
+    jester = Class.new(actor)
  273
+    actor.proxy = 'http://nomad'
  274
+    assert_equal actor.proxy, jester.proxy
  275
+    assert jester.proxy.frozen?
  276
+
  277
+    # Subclasses are always equal to superclass proxy when not overridden
  278
+    fruit = Class.new(ActiveResource::Base)
  279
+    apple = Class.new(fruit)
  280
+
  281
+    fruit.proxy = 'http://market'
  282
+    assert_equal fruit.proxy, apple.proxy, 'subclass did not adopt changes from parent class'
  283
+
  284
+    fruit.proxy = 'http://supermarket'
  285
+    assert_equal fruit.proxy, apple.proxy, 'subclass did not adopt changes from parent class'
  286
+  end
  287
+
224 288
   def test_user_reader_uses_superclass_user_until_written
225 289
     # Superclass is Object so returns nil.
226 290
     assert_nil ActiveResource::Base.user
10  activeresource/test/connection_test.rb
@@ -101,6 +101,16 @@ def test_site_accessor_accepts_uri_or_string_argument
101 101
     assert_equal site, @conn.site
102 102
   end
103 103
 
  104
+  def test_proxy_accessor_accepts_uri_or_string_argument
  105
+    proxy = URI.parse("http://proxy_user:proxy_password@proxy.local:4242")
  106
+
  107
+    assert_nothing_raised { @conn.proxy = "http://proxy_user:proxy_password@proxy.local:4242" }
  108
+    assert_equal proxy, @conn.proxy
  109
+
  110
+    assert_nothing_raised { @conn.proxy = proxy }
  111
+    assert_equal proxy, @conn.proxy
  112
+  end
  113
+
104 114
   def test_timeout_accessor
105 115
     @conn.timeout = 5
106 116
     assert_equal 5, @conn.timeout
4  activeresource/test/fixtures/proxy.rb
... ...
@@ -0,0 +1,4 @@
  1
+class ProxyResource < ActiveResource::Base
  2
+  self.site = "http://localhost"
  3
+  self.proxy = "http://user:password@proxy.local:3000"
  4
+end

0 notes on commit 4d15528

Please sign in to comment.
Something went wrong with that request. Please try again.