diff --git a/Gemfile b/Gemfile index 70203b9..d35011c 100644 --- a/Gemfile +++ b/Gemfile @@ -16,6 +16,7 @@ group :test do gem 'aruba' gem 'cucumber', '~> 2.3' gem 'webmock' + gem 'addressable' end group :development, :test do diff --git a/lib/httparty/request.rb b/lib/httparty/request.rb index ec4af5b..2c5e0eb 100644 --- a/lib/httparty/request.rb +++ b/lib/httparty/request.rb @@ -71,7 +71,7 @@ module HTTParty @path = if uri.is_a?(uri_adapter) uri elsif String.try_convert(uri) - uri_adapter.parse uri + uri_adapter.parse(uri).normalize else raise ArgumentError, "bad argument (expected #{uri_adapter} object or URI string)" @@ -95,9 +95,9 @@ module HTTParty end if path.relative? && path.host - new_uri = options[:uri_adapter].parse("#{@last_uri.scheme}:#{path}") + new_uri = options[:uri_adapter].parse("#{@last_uri.scheme}:#{path}").normalize elsif path.relative? - new_uri = options[:uri_adapter].parse("#{base_uri}#{path}") + new_uri = options[:uri_adapter].parse("#{base_uri}#{path}").normalize else new_uri = path.clone end @@ -305,7 +305,7 @@ module HTTParty def handle_host_redirection check_duplicate_location_header - redirect_path = options[:uri_adapter].parse last_response['location'] + redirect_path = options[:uri_adapter].parse(last_response['location']).normalize return if redirect_path.relative? || path.host == redirect_path.host @changed_hosts = true end diff --git a/spec/httparty_spec.rb b/spec/httparty_spec.rb index 11f85c5..22e8b0e 100644 --- a/spec/httparty_spec.rb +++ b/spec/httparty_spec.rb @@ -405,42 +405,61 @@ RSpec.describe HTTParty do end describe "uri_adapter" do - - require 'forwardable' - class CustomURIAdaptor - extend Forwardable - def_delegators :@uri, :userinfo, :relative?, :query, :query=, :scheme, :path, :host, :port - - def initialize uri - @uri = uri + context 'with Addressable::URI' do + before do + @klass.uri_adapter(Addressable::URI) end - def self.parse uri - new URI.parse uri + it 'handles international domains' do + uri = 'http://xn--i-7iqv272g.ws/' + stub_request(:get, uri).to_return(body: 'stuff') + + response = @klass.get('http://i❤️.ws') + expect(response.parsed_response).to eq('stuff') + expect(response.request.uri.to_s).to eq(uri) end end - let(:uri_adapter) { CustomURIAdaptor } + context 'with custom URI Adaptor' do + require 'forwardable' + class CustomURIAdaptor + extend Forwardable + def_delegators :@uri, :userinfo, :relative?, :query, :query=, :scheme, :path, :host, :port - it "should set the uri_adapter" do - @klass.uri_adapter uri_adapter - expect(@klass.default_options[:uri_adapter]).to be uri_adapter + def initialize(uri) + @uri = uri + end + + def self.parse(uri) + new(URI.parse(uri)) + end + + def normalize + self + end + end + + let(:uri_adapter) { CustomURIAdaptor } + + it "should set the uri_adapter" do + @klass.uri_adapter uri_adapter + expect(@klass.default_options[:uri_adapter]).to be uri_adapter + end + + it "should raise an ArgumentError if uri_adapter doesn't implement parse method" do + expect do + @klass.uri_adapter double() + end.to raise_error(ArgumentError) + end + + + it "should process a request with a uri instance parsed from the uri_adapter" do + uri = 'http://foo.com/bar' + stub_request(:get, uri).to_return(body: 'stuff') + @klass.uri_adapter uri_adapter + expect(@klass.get(uri).parsed_response).to eq('stuff') + end end - - it "should raise an ArgumentError if uri_adapter doesn't implement parse method" do - expect do - @klass.uri_adapter double() - end.to raise_error(ArgumentError) - end - - - it "should process a request with a uri instance parsed from the uri_adapter" do - uri = 'http://foo.com/bar' - stub_request(:get, uri).to_return(body: 'stuff') - @klass.uri_adapter uri_adapter - expect(@klass.get(uri).parsed_response).to eq('stuff') - end - end describe "connection_adapter" do