mirror of
https://github.com/jnunemaker/httparty
synced 2023-03-27 23:23:07 -04:00
Allow custom query string normalization
Useful for changing the Rails-style querystrings, i.e. key[]=1&key[]=2 could become key=1&key=2 Closes gh-8
This commit is contained in:
parent
2f42d99a63
commit
a33741df46
3 changed files with 89 additions and 3 deletions
|
@ -201,6 +201,37 @@ module HTTParty
|
|||
default_options[:pem] = pem_contents
|
||||
end
|
||||
|
||||
# Override the way query strings are normalized.
|
||||
# Helpful for overriding the default rails normalization of Array queries.
|
||||
#
|
||||
# For a query:
|
||||
# get '/', :query => {:selected_ids => [1,2,3]}
|
||||
#
|
||||
# The default query string normalizer returns:
|
||||
# /?selected_ids[]=1&selected_ids[]=2&selected_ids[]=3
|
||||
#
|
||||
# Let's change it to this:
|
||||
# /?selected_ids=1&selected_ids=2&selected_ids=3
|
||||
#
|
||||
# Pass a Proc to the query normalizer which accepts the yielded query.
|
||||
#
|
||||
# @example Modifying Array query strings
|
||||
# class ServiceWrapper
|
||||
# include HTTParty
|
||||
#
|
||||
# query_string_normalizer proc { |query|
|
||||
# query.map do |key, value|
|
||||
# value.map {|v| "#{key}=#{v}"}
|
||||
# end.join('&')
|
||||
# }
|
||||
# end
|
||||
#
|
||||
# @param [Proc] normalizer the new normalizer
|
||||
# @yield [Hash] query hash option
|
||||
def query_string_normalizer(normalizer)
|
||||
default_options[:query_string_normalizer] = normalizer
|
||||
end
|
||||
|
||||
# Allows setting an OpenSSL certificate authority file
|
||||
#
|
||||
# class Foo
|
||||
|
|
|
@ -103,7 +103,7 @@ module HTTParty
|
|||
end
|
||||
|
||||
def body
|
||||
options[:body].is_a?(Hash) ? options[:body].to_params : options[:body]
|
||||
options[:body].is_a?(Hash) ? normalize_query(options[:body]) : options[:body]
|
||||
end
|
||||
|
||||
def credentials
|
||||
|
@ -118,6 +118,18 @@ module HTTParty
|
|||
credentials[:password]
|
||||
end
|
||||
|
||||
def normalize_query(query)
|
||||
if query_string_normalizer
|
||||
query_string_normalizer.call(query)
|
||||
else
|
||||
query.to_params
|
||||
end
|
||||
end
|
||||
|
||||
def query_string_normalizer
|
||||
options[:query_string_normalization]
|
||||
end
|
||||
|
||||
def setup_raw_request
|
||||
@raw_request = http_method.new(uri.request_uri)
|
||||
@raw_request.body = body if body
|
||||
|
@ -146,12 +158,13 @@ module HTTParty
|
|||
query_string_parts << uri.query unless uri.query.nil?
|
||||
|
||||
if options[:query].is_a?(Hash)
|
||||
query_string_parts << options[:default_params].merge(options[:query]).to_params
|
||||
query_string_parts << normalize_query(options[:default_params].merge(options[:query]))
|
||||
else
|
||||
query_string_parts << options[:default_params].to_params unless options[:default_params].empty?
|
||||
query_string_parts << normalize_query(options[:default_params]) unless options[:default_params].empty?
|
||||
query_string_parts << options[:query] unless options[:query].nil?
|
||||
end
|
||||
|
||||
|
||||
query_string_parts.size > 0 ? query_string_parts.join('&') : nil
|
||||
end
|
||||
|
||||
|
|
|
@ -5,6 +5,18 @@ describe HTTParty::Request do
|
|||
@request = HTTParty::Request.new(Net::HTTP::Get, 'http://api.foo.com/v1', :format => :xml)
|
||||
end
|
||||
|
||||
let(:array_normalization_proc) do
|
||||
proc do |query|
|
||||
query.map do |key, value|
|
||||
if value.is_a?(Array)
|
||||
value.map {|v| "#{key}=#{v}"}
|
||||
else
|
||||
{key => value}.to_params
|
||||
end
|
||||
end.flatten.sort.join('&')
|
||||
end
|
||||
end
|
||||
|
||||
describe "initialization" do
|
||||
it "sets parser to HTTParty::Parser" do
|
||||
request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com')
|
||||
|
@ -74,6 +86,36 @@ describe HTTParty::Request do
|
|||
@request.options[:default_params] = {}
|
||||
@request.uri.query.should be_nil
|
||||
end
|
||||
|
||||
it "respects the query string normalization proc" do
|
||||
@request.options[:query_string_normalization] = array_normalization_proc
|
||||
@request.options[:query] = {:page => 1, :foo => %w(bar baz)}
|
||||
URI.unescape(@request.uri.query).should == "foo=bar&foo=baz&page=1"
|
||||
end
|
||||
|
||||
context "when representing an array" do
|
||||
it "doesn't modify strings" do
|
||||
@request.options[:query] = "foo=bar&foo=baz"
|
||||
URI.unescape(@request.uri.query).should == "foo=bar&foo=baz"
|
||||
end
|
||||
|
||||
it "converts a ruby array into a Rails supported query string" do
|
||||
@request.options[:query] = {:foo => %w(bar baz)}
|
||||
URI.unescape(@request.uri.query).should == "foo[]=bar&foo[]=baz"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#setup_raw_request" do
|
||||
context "when query_string_normalization is set" do
|
||||
it "sets the body to the return value of the proc" do
|
||||
@request.options[:query_string_normalization] = array_normalization_proc
|
||||
@request.options[:body] = {:page => 1, :foo => %w(bar baz)}
|
||||
@request.send(:setup_raw_request)
|
||||
body = @request.instance_variable_get(:@raw_request).body
|
||||
URI.unescape(body).should == "foo=bar&foo=baz&page=1"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue