mirror of
https://github.com/jnunemaker/httparty
synced 2023-03-27 23:23:07 -04:00
Normalize urls with URI adapter to allow International Domain Names support (#668)
* Normalize urls with URI adapter to allow idns support * Fix normalization update specs
This commit is contained in:
parent
b9a54d8f73
commit
54b7949b91
3 changed files with 53 additions and 33 deletions
1
Gemfile
1
Gemfile
|
@ -16,6 +16,7 @@ group :test do
|
|||
gem 'aruba'
|
||||
gem 'cucumber', '~> 2.3'
|
||||
gem 'webmock'
|
||||
gem 'addressable'
|
||||
end
|
||||
|
||||
group :development, :test do
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue