From c4ca3a0615fae29806c64a0ad1c2dfd8b68114ea Mon Sep 17 00:00:00 2001 From: "Brian D. Burns" Date: Wed, 16 Oct 2013 15:19:29 -0400 Subject: [PATCH] [aws|storage] ensure connection uses correct scheme, host and port Currently, the `:scheme`, `:host` and `:port` are determined in `#request_params` and passed as request parameters. However, passing these as request parameters does not override the URI used to establish the connection, which is used by Excon for the underlying socket. Excon now considers these to be invalid request parameters. This patch defers establishing the connection until the proper URI is known, while still allowing the `:persistent` option to work as long as the URI doesn't change. --- lib/fog/aws/storage.rb | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/lib/fog/aws/storage.rb b/lib/fog/aws/storage.rb index 3f0356198..69c7680da 100644 --- a/lib/fog/aws/storage.rb +++ b/lib/fog/aws/storage.rb @@ -184,9 +184,9 @@ module Fog if params[:scheme] scheme = params[:scheme] - port = params[:port] + port = params[:port] || DEFAULT_SCHEME_PORT[scheme] else - scheme = @scheme || DEFAULT_SCHEME + scheme = @scheme port = @port end if DEFAULT_SCHEME_PORT[scheme] == port @@ -225,7 +225,7 @@ module Fog :host => host, :port => port, :path => path, - :headers => headers, + :headers => headers }) # @@ -418,12 +418,10 @@ module Fog @port = options[:port] || DEFAULT_SCHEME_PORT[@scheme] @path_style = options[:path_style] || false end - - @connection = Fog::Connection.new("#{@scheme}://#{@host}:#{@port}#{@path}", @persistent, @connection_options) end def reload - @connection.reset + @connection.reset if @connection end def signature(params, expires) @@ -493,6 +491,20 @@ DATA @hmac = Fog::HMAC.new('sha1', @aws_secret_access_key) end + def connection(scheme, host, port) + uri = "#{scheme}://#{host}:#{port}" + if @persistent + unless uri == @connection_uri + @connection_uri = uri + reload + @connection = nil + end + else + @connection = nil + end + @connection ||= Fog::Connection.new(uri, @persistent, @connection_options) + end + def request(params, &block) refresh_credentials_if_expired @@ -502,7 +514,9 @@ DATA signature = signature(params, expires) params = request_params(params) - params.delete(:port) unless params[:port] + scheme = params.delete(:scheme) + host = params.delete(:host) + port = params.delete(:port) || DEFAULT_SCHEME_PORT[scheme] params[:headers]['Date'] = expires params[:headers]['Authorization'] = "AWS #{@aws_access_key_id}:#{signature}" @@ -510,12 +524,12 @@ DATA original_params = params.dup begin - response = @connection.request(params, &block) + response = connection(scheme, host, port).request(params, &block) rescue Excon::Errors::TemporaryRedirect => error headers = (error.response.is_a?(Hash) ? error.response[:headers] : error.response.headers) uri = URI.parse(headers['Location']) Fog::Logger.warning("fog: followed redirect to #{uri.host}, connecting to the matching region will be more performant") - response = Fog::Connection.new("#{@scheme}://#{uri.host}:#{@port}", false, @connection_options).request(original_params, &block) + response = Fog::Connection.new("#{uri.scheme}://#{uri.host}:#{uri.port}", false, @connection_options).request(original_params, &block) end response