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
|
default_options[:pem] = pem_contents
|
||||||
end
|
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
|
# Allows setting an OpenSSL certificate authority file
|
||||||
#
|
#
|
||||||
# class Foo
|
# class Foo
|
||||||
|
|
|
@ -103,7 +103,7 @@ module HTTParty
|
||||||
end
|
end
|
||||||
|
|
||||||
def body
|
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
|
end
|
||||||
|
|
||||||
def credentials
|
def credentials
|
||||||
|
@ -118,6 +118,18 @@ module HTTParty
|
||||||
credentials[:password]
|
credentials[:password]
|
||||||
end
|
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
|
def setup_raw_request
|
||||||
@raw_request = http_method.new(uri.request_uri)
|
@raw_request = http_method.new(uri.request_uri)
|
||||||
@raw_request.body = body if body
|
@raw_request.body = body if body
|
||||||
|
@ -146,12 +158,13 @@ module HTTParty
|
||||||
query_string_parts << uri.query unless uri.query.nil?
|
query_string_parts << uri.query unless uri.query.nil?
|
||||||
|
|
||||||
if options[:query].is_a?(Hash)
|
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
|
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?
|
query_string_parts << options[:query] unless options[:query].nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
query_string_parts.size > 0 ? query_string_parts.join('&') : nil
|
query_string_parts.size > 0 ? query_string_parts.join('&') : nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,18 @@ describe HTTParty::Request do
|
||||||
@request = HTTParty::Request.new(Net::HTTP::Get, 'http://api.foo.com/v1', :format => :xml)
|
@request = HTTParty::Request.new(Net::HTTP::Get, 'http://api.foo.com/v1', :format => :xml)
|
||||||
end
|
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
|
describe "initialization" do
|
||||||
it "sets parser to HTTParty::Parser" do
|
it "sets parser to HTTParty::Parser" do
|
||||||
request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com')
|
request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com')
|
||||||
|
@ -74,6 +86,36 @@ describe HTTParty::Request do
|
||||||
@request.options[:default_params] = {}
|
@request.options[:default_params] = {}
|
||||||
@request.uri.query.should be_nil
|
@request.uri.query.should be_nil
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue