Replace deprecated URI.escape with a customized CGI.escape

Replaces my original attempt in #319 in a way that doesn't depend on
`URI.encode_www_form` which doesn't exist in 1.8.7. This should
hopefully get us the best of all worlds.

Caveats around use of `+` instead of `%20` as detailed in #319 still
apply.

Fixes #286.
This commit is contained in:
Brandur 2015-10-06 14:23:52 -07:00
parent 0485de9669
commit eb8787754c
4 changed files with 15 additions and 8 deletions

View File

@ -1,3 +1,5 @@
require "cgi"
module Stripe
module Util
def self.objects_to_ids(h)
@ -98,17 +100,24 @@ module Stripe
# `&`).
def self.encode_parameters(params)
Util.flatten_params(params).
map { |k,v| "#{k}=#{Util.url_encode(v)}" }.join('&')
map { |k,v| "#{url_encode(k)}=#{url_encode(v)}" }.join('&')
end
# Encodes a string in a way that makes it suitable for use in a set of
# query parameters in a URI or in a set of form parameters in a request
# body.
def self.url_encode(key)
URI.escape(key.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
CGI.escape(key.to_s).
# Don't use strict form encoding by changing the square bracket control
# characters back to their literals. This is fine by the server, and
# makes these parameter strings easier to read.
gsub('%5B', '[').gsub('%5D', ']')
end
def self.flatten_params(params, parent_key=nil)
result = []
params.each do |key, value|
calculated_key = parent_key ? "#{parent_key}[#{url_encode(key)}]" : url_encode(key)
calculated_key = parent_key ? "#{parent_key}[#{key}]" : "#{key}"
if value.is_a?(Hash)
result += flatten_params(value, calculated_key)
elsif value.is_a?(Array)

View File

@ -68,7 +68,7 @@ module Stripe
@mock.expects(:post).
once.
with('https://api.stripe.com/v1/accounts/acct_foo', nil, 'legal_entity[address][line1]=2%20Three%20Four&legal_entity[first_name]=Bob').
with('https://api.stripe.com/v1/accounts/acct_foo', nil, 'legal_entity[address][line1]=2+Three+Four&legal_entity[first_name]=Bob').
returns(make_response(resp))
a = Stripe::Account.retrieve('acct_foo')

View File

@ -230,7 +230,7 @@ module Stripe
should "urlencode values in GET params" do
response = make_response(make_charge_array)
@mock.expects(:get).with("#{Stripe.api_base}/v1/charges?customer=test%20customer", nil, nil).returns(response)
@mock.expects(:get).with("#{Stripe.api_base}/v1/charges?customer=test+customer", nil, nil).returns(response)
charges = Stripe::Charge.list(:customer => 'test customer').data
assert charges.kind_of? Array
end

View File

@ -21,9 +21,7 @@ module Stripe
assert_equal "foo", Stripe::Util.url_encode(:foo)
assert_equal "foo%2B", Stripe::Util.url_encode("foo+")
assert_equal "foo%26", Stripe::Util.url_encode("foo&")
# Actually, we're going to alter the behavior of #url_encode slightly to
# simplify the form encoding path. This does not yet succeed.
# assert_equal "foo[bar]", Stripe::Util.url_encode("foo[bar]")
assert_equal "foo[bar]", Stripe::Util.url_encode("foo[bar]")
end
should "#flatten_params should encode parameters according to Rails convention" do