diff --git a/history.md b/history.md index f941c81..7da477a 100644 --- a/history.md +++ b/history.md @@ -32,6 +32,8 @@ This release is largely API compatible, but makes several breaking changes. Set-Cookie, which is special) by joining the values with a comma space, compliant with RFC 7230 - Don't set basic auth header if explicit `Authorization` header is specified +- Add `:proxy` option to requests, which can be used for thread-safe + per-request proxy configuration, overriding `RestClient.proxy` # 1.8.0 diff --git a/lib/restclient/request.rb b/lib/restclient/request.rb index a40f17b..253a44c 100644 --- a/lib/restclient/request.rb +++ b/lib/restclient/request.rb @@ -21,6 +21,8 @@ module RestClient # * :block_response call the provided block with the HTTPResponse as parameter # * :raw_response return a low-level RawResponse instead of a Response # * :max_redirects maximum number of redirections (default to 10) + # * :proxy An HTTP proxy URI to use for this request. Any value here + # (including nil) will override RestClient.proxy. # * :verify_ssl enable ssl verification, possible values are constants from # OpenSSL::SSL::VERIFY_*, defaults to OpenSSL::SSL::VERIFY_PEER # * :read_timeout and :open_timeout are how long to wait for a response and @@ -35,8 +37,8 @@ module RestClient # TODO: rename timeout to read_timeout - attr_reader :method, :url, :headers, :cookies, - :payload, :user, :password, :read_timeout, :max_redirects, + attr_reader :method, :url, :headers, :cookies, :payload, :proxy, + :user, :password, :read_timeout, :max_redirects, :open_timeout, :raw_response, :processed_headers, :args, :ssl_opts @@ -129,6 +131,8 @@ module RestClient @block_response = args[:block_response] @raw_response = args[:raw_response] || false + @proxy = args.fetch(:proxy) if args.include?(:proxy) + @ssl_opts = {} if args.include?(:verify_ssl) @@ -260,8 +264,17 @@ module RestClient end def net_http_class - if RestClient.proxy + proxy_uri = nil + + if defined?(@proxy) + if @proxy + proxy_uri = URI.parse(@proxy) + end + elsif RestClient.proxy proxy_uri = URI.parse(RestClient.proxy) + end + + if proxy_uri Net::HTTP::Proxy(proxy_uri.hostname, proxy_uri.port, proxy_uri.user, proxy_uri.password) else Net::HTTP diff --git a/spec/unit/request_spec.rb b/spec/unit/request_spec.rb index a6ab316..878fe5e 100644 --- a/spec/unit/request_spec.rb +++ b/spec/unit/request_spec.rb @@ -426,6 +426,21 @@ describe RestClient::Request, :include_helpers do it "creates a non-proxy class if a proxy url is not given" do @request.net_http_class.proxy_class?.should be_falsey end + + it "disables proxy on a per-request basis" do + RestClient.stub(:proxy).and_return('http://example.com') + @request.net_http_class.proxy_class?.should be true + + disabled_req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :proxy => nil) + disabled_req.net_http_class.proxy_class?.should be_falsey + end + + it "sets proxy on a per-request basis" do + @request.net_http_class.proxy_class?.should be_falsey + + req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :proxy => 'http://example.com') + req.net_http_class.proxy_class?.should be true + end end