HTTP proxy support
[#2133 state:committed] Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
This commit is contained in:
parent
5786395760
commit
4d1552810f
|
@ -1,3 +1,8 @@
|
|||
*Edge*
|
||||
|
||||
* HTTP proxy support. #2133 [Marshall Huss, Sébastien Dabet]
|
||||
|
||||
|
||||
*2.3.2 [Final] (March 15, 2009)*
|
||||
|
||||
* Nothing new, just included in 2.3.2
|
||||
|
|
|
@ -257,6 +257,22 @@ module ActiveResource
|
|||
end
|
||||
end
|
||||
|
||||
# Gets the \proxy variable if a proxy is required
|
||||
def proxy
|
||||
# Not using superclass_delegating_reader. See +site+ for explanation
|
||||
if defined?(@proxy)
|
||||
@proxy
|
||||
elsif superclass != Object && superclass.proxy
|
||||
superclass.proxy.dup.freeze
|
||||
end
|
||||
end
|
||||
|
||||
# Sets the URI of the http proxy to the value in the +proxy+ argument.
|
||||
def proxy=(proxy)
|
||||
@connection = nil
|
||||
@proxy = proxy.nil? ? nil : create_proxy_uri_from(proxy)
|
||||
end
|
||||
|
||||
# Gets the \user for REST HTTP authentication.
|
||||
def user
|
||||
# Not using superclass_delegating_reader. See +site+ for explanation
|
||||
|
@ -332,6 +348,7 @@ module ActiveResource
|
|||
def connection(refresh = false)
|
||||
if defined?(@connection) || superclass == Object
|
||||
@connection = Connection.new(site, format) if refresh || @connection.nil?
|
||||
@connection.proxy = proxy if proxy
|
||||
@connection.user = user if user
|
||||
@connection.password = password if password
|
||||
@connection.timeout = timeout if timeout
|
||||
|
@ -622,6 +639,11 @@ module ActiveResource
|
|||
site.is_a?(URI) ? site.dup : URI.parse(site)
|
||||
end
|
||||
|
||||
# Accepts a URI and creates the proxy URI from that.
|
||||
def create_proxy_uri_from(proxy)
|
||||
proxy.is_a?(URI) ? proxy.dup : URI.parse(proxy)
|
||||
end
|
||||
|
||||
# contains a set of the current prefix parameters.
|
||||
def prefix_parameters
|
||||
@prefix_parameters ||= prefix_source.scan(/:\w+/).map { |key| key[1..-1].to_sym }.to_set
|
||||
|
|
|
@ -16,7 +16,7 @@ module ActiveResource
|
|||
:delete => 'Accept'
|
||||
}
|
||||
|
||||
attr_reader :site, :user, :password, :timeout
|
||||
attr_reader :site, :user, :password, :timeout, :proxy
|
||||
attr_accessor :format
|
||||
|
||||
class << self
|
||||
|
@ -41,6 +41,11 @@ module ActiveResource
|
|||
@password = URI.decode(@site.password) if @site.password
|
||||
end
|
||||
|
||||
# Set the proxy for remote service.
|
||||
def proxy=(proxy)
|
||||
@proxy = proxy.is_a?(URI) ? proxy : URI.parse(proxy)
|
||||
end
|
||||
|
||||
# Sets the user for remote service.
|
||||
def user=(user)
|
||||
@user = user
|
||||
|
@ -132,8 +137,13 @@ module ActiveResource
|
|||
# Creates new Net::HTTP instance for communication with the
|
||||
# remote service and resources.
|
||||
def http
|
||||
http = Net::HTTP.new(@site.host, @site.port)
|
||||
http.use_ssl = @site.is_a?(URI::HTTPS)
|
||||
http =
|
||||
if @proxy
|
||||
Net::HTTP.new(@site.host, @site.port, @proxy.host, @proxy.port, @proxy.user, @proxy.password)
|
||||
else
|
||||
Net::HTTP.new(@site.host, @site.port)
|
||||
end
|
||||
http.use_ssl = @site.is_a?(URI::HTTPS)
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl?
|
||||
http.read_timeout = @timeout if @timeout # If timeout is not set, the default Net::HTTP timeout (60s) is used.
|
||||
http
|
||||
|
|
|
@ -3,6 +3,7 @@ require "fixtures/person"
|
|||
require "fixtures/customer"
|
||||
require "fixtures/street_address"
|
||||
require "fixtures/beast"
|
||||
require "fixtures/proxy"
|
||||
require 'active_support/core_ext/hash/conversions'
|
||||
|
||||
class BaseTest < Test::Unit::TestCase
|
||||
|
@ -125,6 +126,28 @@ class BaseTest < Test::Unit::TestCase
|
|||
assert_nil actor.site
|
||||
end
|
||||
|
||||
def test_proxy_accessor_accepts_uri_or_string_argument
|
||||
proxy = URI.parse('http://localhost')
|
||||
|
||||
assert_nothing_raised { Person.proxy = 'http://localhost' }
|
||||
assert_equal proxy, Person.proxy
|
||||
|
||||
assert_nothing_raised { Person.proxy = proxy }
|
||||
assert_equal proxy, Person.proxy
|
||||
end
|
||||
|
||||
def test_should_use_proxy_prefix_and_credentials
|
||||
assert_equal 'http://user:password@proxy.local:3000', ProxyResource.proxy.to_s
|
||||
end
|
||||
|
||||
def test_proxy_variable_can_be_reset
|
||||
actor = Class.new(ActiveResource::Base)
|
||||
assert_nil actor.site
|
||||
actor.proxy = 'http://localhost:31337'
|
||||
actor.proxy = nil
|
||||
assert_nil actor.site
|
||||
end
|
||||
|
||||
def test_should_accept_setting_user
|
||||
Forum.user = 'david'
|
||||
assert_equal('david', Forum.user)
|
||||
|
@ -221,6 +244,47 @@ class BaseTest < Test::Unit::TestCase
|
|||
assert_equal fruit.site, apple.site, 'subclass did not adopt changes from parent class'
|
||||
end
|
||||
|
||||
def test_proxy_reader_uses_superclass_site_until_written
|
||||
# Superclass is Object so returns nil.
|
||||
assert_nil ActiveResource::Base.proxy
|
||||
assert_nil Class.new(ActiveResource::Base).proxy
|
||||
|
||||
# Subclass uses superclass proxy.
|
||||
actor = Class.new(Person)
|
||||
assert_equal Person.proxy, actor.proxy
|
||||
|
||||
# Subclass returns frozen superclass copy.
|
||||
assert !Person.proxy.frozen?
|
||||
assert actor.proxy.frozen?
|
||||
|
||||
# Changing subclass proxy doesn't change superclass site.
|
||||
actor.proxy = 'http://localhost:31337'
|
||||
assert_not_equal Person.proxy, actor.proxy
|
||||
|
||||
# Changed subclass proxy is not frozen.
|
||||
assert !actor.proxy.frozen?
|
||||
|
||||
# Changing superclass proxy doesn't overwrite subclass site.
|
||||
Person.proxy = 'http://somewhere.else'
|
||||
assert_not_equal Person.proxy, actor.proxy
|
||||
|
||||
# Changing superclass proxy after subclassing changes subclass site.
|
||||
jester = Class.new(actor)
|
||||
actor.proxy = 'http://nomad'
|
||||
assert_equal actor.proxy, jester.proxy
|
||||
assert jester.proxy.frozen?
|
||||
|
||||
# Subclasses are always equal to superclass proxy when not overridden
|
||||
fruit = Class.new(ActiveResource::Base)
|
||||
apple = Class.new(fruit)
|
||||
|
||||
fruit.proxy = 'http://market'
|
||||
assert_equal fruit.proxy, apple.proxy, 'subclass did not adopt changes from parent class'
|
||||
|
||||
fruit.proxy = 'http://supermarket'
|
||||
assert_equal fruit.proxy, apple.proxy, 'subclass did not adopt changes from parent class'
|
||||
end
|
||||
|
||||
def test_user_reader_uses_superclass_user_until_written
|
||||
# Superclass is Object so returns nil.
|
||||
assert_nil ActiveResource::Base.user
|
||||
|
|
|
@ -101,6 +101,16 @@ class ConnectionTest < Test::Unit::TestCase
|
|||
assert_equal site, @conn.site
|
||||
end
|
||||
|
||||
def test_proxy_accessor_accepts_uri_or_string_argument
|
||||
proxy = URI.parse("http://proxy_user:proxy_password@proxy.local:4242")
|
||||
|
||||
assert_nothing_raised { @conn.proxy = "http://proxy_user:proxy_password@proxy.local:4242" }
|
||||
assert_equal proxy, @conn.proxy
|
||||
|
||||
assert_nothing_raised { @conn.proxy = proxy }
|
||||
assert_equal proxy, @conn.proxy
|
||||
end
|
||||
|
||||
def test_timeout_accessor
|
||||
@conn.timeout = 5
|
||||
assert_equal 5, @conn.timeout
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
class ProxyResource < ActiveResource::Base
|
||||
self.site = "http://localhost"
|
||||
self.proxy = "http://user:password@proxy.local:3000"
|
||||
end
|
Loading…
Reference in New Issue