Skip to content

Commit

Permalink
Normalize urls with URI adapter to allow International Domain Names s…
Browse files Browse the repository at this point in the history
…upport (#668)

* Normalize urls with URI adapter to allow idns support

* Fix normalization update specs
  • Loading branch information
TheSmartnik authored Aug 30, 2019
1 parent b9a54d8 commit 54b7949
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 29 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ group :test do
gem 'aruba'
gem 'cucumber', '~> 2.3'
gem 'webmock'
gem 'addressable'
end

group :development, :test do
Expand Down
8 changes: 4 additions & 4 deletions lib/httparty/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def path=(uri)
@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)"
Expand All @@ -95,9 +95,9 @@ def uri
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
Expand Down Expand Up @@ -305,7 +305,7 @@ def handle_response(body, &block)

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
Expand Down
69 changes: 44 additions & 25 deletions spec/httparty_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -405,42 +405,61 @@ def self.parse(body)
end

describe "uri_adapter" do
context 'with Addressable::URI' do
before do
@klass.uri_adapter(Addressable::URI)
end

require 'forwardable'
class CustomURIAdaptor
extend Forwardable
def_delegators :@uri, :userinfo, :relative?, :query, :query=, :scheme, :path, :host, :port
it 'handles international domains' do
uri = 'http://xn--i-7iqv272g.ws/'
stub_request(:get, uri).to_return(body: 'stuff')

def initialize uri
@uri = uri
response = @klass.get('http://i❤️.ws')
expect(response.parsed_response).to eq('stuff')
expect(response.request.uri.to_s).to eq(uri)
end
end

context 'with custom URI Adaptor' do
require 'forwardable'
class CustomURIAdaptor
extend Forwardable
def_delegators :@uri, :userinfo, :relative?, :query, :query=, :scheme, :path, :host, :port

def initialize(uri)
@uri = uri
end

def self.parse(uri)
new(URI.parse(uri))
end

def self.parse uri
new URI.parse uri
def normalize
self
end
end
end

let(:uri_adapter) { CustomURIAdaptor }
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 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 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')
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

end

describe "connection_adapter" do
Expand Down

0 comments on commit 54b7949

Please # to comment.