Skip to content

Commit

Permalink
Allow overriding parameter encoding to support services that don't br…
Browse files Browse the repository at this point in the history
…acketize repeated parameters
  • Loading branch information
sqrrrl committed Aug 8, 2012
1 parent 6062767 commit dc8409d
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 13 deletions.
17 changes: 9 additions & 8 deletions lib/faraday/connection.rb
Expand Up @@ -74,8 +74,9 @@ def initialize(url = nil, options = {})
@headers = Utils::Headers.new @headers = Utils::Headers.new
@params = Utils::ParamsHash.new @params = Utils::ParamsHash.new
@options = options[:request] || {} @options = options[:request] || {}
@options[:param_encoding] ||= :nested
@ssl = options[:ssl] || {} @ssl = options[:ssl] || {}

@parallel_manager = nil @parallel_manager = nil
@default_parallel_manager = options[:parallel_manager] @default_parallel_manager = options[:parallel_manager]


Expand Down Expand Up @@ -438,27 +439,27 @@ def build_url(url, extra_params = nil)


query_values = self.params.dup.merge_query(uri.query) query_values = self.params.dup.merge_query(uri.query)
query_values.update extra_params if extra_params query_values.update extra_params if extra_params
uri.query = query_values.empty? ? nil : query_values.to_query uri.query = query_values.empty? ? nil : query_values.to_query(options[:param_encoding])


uri uri
end end


# Internal: Build an absolute URL based on url_prefix. # Internal: Build an absolute URL based on url_prefix.
# #
# url - A String or URI-like object # url - A String or URI-like object
# params - A Faraday::Utils::ParamsHash to replace the query values # params - A Faraday::Utils::ParamsHash to replace the query values
# of the resulting url (default: nil). # of the resulting url (default: nil).
# # param_encoding - Scheme for encoding query parameters
# Returns the resulting URI instance. # Returns the resulting URI instance.
def build_exclusive_url(url, params = nil) def build_exclusive_url(url, params = nil, param_encoding = nil)
url = nil if url.respond_to?(:empty?) and url.empty? url = nil if url.respond_to?(:empty?) and url.empty?
base = url_prefix base = url_prefix
if url and base.path and base.path !~ /\/$/ if url and base.path and base.path !~ /\/$/
base = base.dup base = base.dup
base.path = base.path + '/' # ensure trailing slash base.path = base.path + '/' # ensure trailing slash
end end
uri = url ? base + url : base uri = url ? base + url : base
uri.query = params.to_query if params uri.query = params.to_query(param_encoding) if params
uri.query = nil if uri.query and uri.query.empty? uri.query = nil if uri.query and uri.query.empty?
uri uri
end end
Expand Down
2 changes: 1 addition & 1 deletion lib/faraday/request.rb
Expand Up @@ -91,7 +91,7 @@ def []=(key, value)
def to_env(connection) def to_env(connection)
{ :method => method, { :method => method,
:body => body, :body => body,
:url => connection.build_exclusive_url(path, params), :url => connection.build_exclusive_url(path, params, options[:param_encoding]),
:request_headers => headers, :request_headers => headers,
:parallel_manager => connection.parallel_manager, :parallel_manager => connection.parallel_manager,
:request => options, :request => options,
Expand Down
3 changes: 2 additions & 1 deletion lib/faraday/request/url_encoded.rb
Expand Up @@ -9,7 +9,8 @@ class << self


def call(env) def call(env)
match_content_type(env) do |data| match_content_type(env) do |data|
env[:body] = Faraday::Utils.build_nested_query data params = Faraday::Utils::ParamsHash[data]
env[:body] = params.to_query(env[:request][:param_encoding])
end end
@app.call env @app.call env
end end
Expand Down
15 changes: 12 additions & 3 deletions lib/faraday/utils.rb
Expand Up @@ -131,8 +131,12 @@ def merge_query(query)
self self
end end


def to_query def to_query(encoding=nil)
Utils.build_nested_query(self) if encoding == :nested
Utils.build_nested_query(self)
else
Utils.build_query(self)
end
end end


private private
Expand Down Expand Up @@ -219,7 +223,12 @@ def normalize_params(params, name, v = nil)
return if k.empty? return if k.empty?


if after == "" if after == ""
params[k] = v if params[k]
params[k] = Array[params[k]] unless params[k].kind_of?(Array)
params[k] << v
else
params[k] = v
end
elsif after == "[]" elsif after == "[]"
params[k] ||= [] params[k] ||= []
raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array) raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
Expand Down
7 changes: 7 additions & 0 deletions test/connection_test.rb
Expand Up @@ -191,6 +191,13 @@ def test_build_url_bracketizes_nested_params_in_query
assert_equal "a%5Bb%5D=c", uri.query assert_equal "a%5Bb%5D=c", uri.query
end end


def test_build_url_without_braketizing_params_in_query
conn = Faraday::Connection.new
conn.options[:param_encoding] = nil
uri = conn.build_url("http://sushi.com/sake.html", 'a' => [1, 2])
assert_equal "a=1&a=2", uri.query
end

def test_build_url_parses_url def test_build_url_parses_url
conn = Faraday::Connection.new conn = Faraday::Connection.new
uri = conn.build_url("http://sushi.com/sake.html") uri = conn.build_url("http://sushi.com/sake.html")
Expand Down
9 changes: 9 additions & 0 deletions test/request_middleware_test.rb
Expand Up @@ -48,6 +48,15 @@ def test_url_encoded_nested
assert_equal expected, Faraday::Utils.parse_nested_query(response.body) assert_equal expected, Faraday::Utils.parse_nested_query(response.body)
end end


def test_url_encoded_non_nested
response = @conn.post('/echo', { :dimensions => ['date', 'location']}) do |req|
req.options[:param_encoding] = nil
end
assert_equal 'application/x-www-form-urlencoded', response.headers['Content-Type']
expected = { 'dimensions' => ['date', 'location'] }
assert_equal expected, Faraday::Utils.parse_nested_query(response.body)
end

def test_url_encoded_unicode def test_url_encoded_unicode
err = capture_warnings { err = capture_warnings {
response = @conn.post('/echo', {:str => "eé cç aã aâ"}) response = @conn.post('/echo', {:str => "eé cç aã aâ"})
Expand Down

0 comments on commit dc8409d

Please sign in to comment.