1
0
Fork 0
mirror of https://github.com/jnunemaker/httparty synced 2023-03-27 23:23:07 -04:00

Allow setting a custom URI adapter

This option allows you to roll out fancier URI parsers like the one
offered by the Addressable gem.

Addressable is a replacement for the URI implementation that is part of
Ruby's standard library. It more closely conforms to RFC 3986, RFC 3987,
and RFC 6570 (level 4), additionally providing support for IRIs and URI
templates. http://addressable.rubyforge.org/
This commit is contained in:
Javier Blanco 2015-05-14 08:12:27 +02:00
parent 097264c99e
commit 9b6748ddbe
4 changed files with 59 additions and 4 deletions

View file

@ -49,6 +49,7 @@ module HTTParty
# * :+maintain_method_across_redirects+: see HTTParty::ClassMethods.maintain_method_across_redirects. # * :+maintain_method_across_redirects+: see HTTParty::ClassMethods.maintain_method_across_redirects.
# * :+no_follow+: see HTTParty::ClassMethods.no_follow. # * :+no_follow+: see HTTParty::ClassMethods.no_follow.
# * :+parser+: see HTTParty::ClassMethods.parser. # * :+parser+: see HTTParty::ClassMethods.parser.
# * :+uri_adapter+: see HTTParty::ClassMethods.uri_adapter
# * :+connection_adapter+: see HTTParty::ClassMethods.connection_adapter. # * :+connection_adapter+: see HTTParty::ClassMethods.connection_adapter.
# * :+pem+: see HTTParty::ClassMethods.pem. # * :+pem+: see HTTParty::ClassMethods.pem.
# * :+query_string_normalizer+: see HTTParty::ClassMethods.query_string_normalizer # * :+query_string_normalizer+: see HTTParty::ClassMethods.query_string_normalizer
@ -419,6 +420,17 @@ module HTTParty
end end
end end
# Allows setting a custom URI adapter.
#
# class Foo
# include HTTParty
# uri_adapter Addressable::URI
# end
def uri_adapter(uri_adapter)
raise ArgumentError, 'The URI adapter should respond to #parse' unless uri_adapter.respond_to?(:parse)
default_options[:uri_adapter] = uri_adapter
end
# Allows setting a custom connection_adapter for the http connections # Allows setting a custom connection_adapter for the http connections
# #
# @example # @example

View file

@ -61,7 +61,8 @@ module HTTParty
attr_reader :uri, :options attr_reader :uri, :options
def initialize(uri, options = {}) def initialize(uri, options = {})
raise ArgumentError, "uri must be a URI, not a #{uri.class}" unless uri.is_a? URI uri_adapter = options[:uri_adapter] || URI
raise ArgumentError, "uri must be a #{uri_adapter}, not a #{uri.class}" unless uri.is_a? uri_adapter
@uri = uri @uri = uri
@options = options @options = options

View file

@ -37,6 +37,7 @@ module HTTParty
default_params: {}, default_params: {},
follow_redirects: true, follow_redirects: true,
parser: Parser, parser: Parser,
uri_adapter: URI,
connection_adapter: ConnectionAdapter connection_adapter: ConnectionAdapter
}.merge(o) }.merge(o)
self.path = path self.path = path
@ -90,13 +91,15 @@ module HTTParty
end end
def URI uri def URI uri
if uri.is_a?(URI) uri_adapter = options[:uri_adapter]
if uri.is_a?(uri_adapter)
uri uri
elsif uri = String.try_convert(uri) elsif uri = String.try_convert(uri)
URI.parse uri uri_adapter.parse uri
else else
raise ArgumentError, raise ArgumentError,
"bad argument (expected URI object or URI string)" "bad argument (expected #{uri_adapter} object or URI string)"
end end
end end

View file

@ -351,6 +351,45 @@ RSpec.describe HTTParty do
end end
end 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
end
def self.parse uri
new URI.parse uri
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'
FakeWeb.register_uri(:get, uri, body: 'stuff')
@klass.uri_adapter uri_adapter
expect(@klass.get(uri).parsed_response).to eq('stuff')
end
end
describe "connection_adapter" do describe "connection_adapter" do
let(:uri) { 'http://google.com/api.json' } let(:uri) { 'http://google.com/api.json' }
let(:connection_adapter) { double('CustomConnectionAdapter') } let(:connection_adapter) { double('CustomConnectionAdapter') }