faraday 0.9.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +276 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +27 -217
  5. data/Rakefile +7 -0
  6. data/UPGRADING.md +55 -0
  7. data/examples/client_spec.rb +65 -0
  8. data/examples/client_test.rb +79 -0
  9. data/lib/faraday/adapter/em_http.rb +149 -101
  10. data/lib/faraday/adapter/em_http_ssl_patch.rb +25 -19
  11. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +18 -15
  12. data/lib/faraday/adapter/em_synchrony.rb +106 -56
  13. data/lib/faraday/adapter/excon.rb +98 -55
  14. data/lib/faraday/adapter/httpclient.rb +89 -55
  15. data/lib/faraday/adapter/net_http.rb +132 -53
  16. data/lib/faraday/adapter/net_http_persistent.rb +70 -28
  17. data/lib/faraday/adapter/patron.rb +92 -38
  18. data/lib/faraday/adapter/rack.rb +30 -13
  19. data/lib/faraday/adapter/test.rb +136 -52
  20. data/lib/faraday/adapter/typhoeus.rb +7 -115
  21. data/lib/faraday/adapter.rb +89 -20
  22. data/lib/faraday/adapter_registry.rb +28 -0
  23. data/lib/faraday/autoload.rb +47 -36
  24. data/lib/faraday/connection.rb +345 -168
  25. data/lib/faraday/dependency_loader.rb +37 -0
  26. data/lib/faraday/encoders/flat_params_encoder.rb +98 -0
  27. data/lib/faraday/encoders/nested_params_encoder.rb +171 -0
  28. data/lib/faraday/error.rb +108 -29
  29. data/lib/faraday/file_part.rb +128 -0
  30. data/lib/faraday/logging/formatter.rb +105 -0
  31. data/lib/faraday/middleware.rb +12 -28
  32. data/lib/faraday/middleware_registry.rb +129 -0
  33. data/lib/faraday/options/connection_options.rb +22 -0
  34. data/lib/faraday/options/env.rb +181 -0
  35. data/lib/faraday/options/proxy_options.rb +28 -0
  36. data/lib/faraday/options/request_options.rb +22 -0
  37. data/lib/faraday/options/ssl_options.rb +59 -0
  38. data/lib/faraday/options.rb +57 -194
  39. data/lib/faraday/param_part.rb +53 -0
  40. data/lib/faraday/parameters.rb +4 -196
  41. data/lib/faraday/rack_builder.rb +74 -39
  42. data/lib/faraday/request/authorization.rb +42 -31
  43. data/lib/faraday/request/basic_authentication.rb +14 -7
  44. data/lib/faraday/request/instrumentation.rb +45 -27
  45. data/lib/faraday/request/multipart.rb +81 -45
  46. data/lib/faraday/request/retry.rb +211 -126
  47. data/lib/faraday/request/token_authentication.rb +15 -10
  48. data/lib/faraday/request/url_encoded.rb +41 -23
  49. data/lib/faraday/request.rb +84 -30
  50. data/lib/faraday/response/logger.rb +22 -48
  51. data/lib/faraday/response/raise_error.rb +38 -14
  52. data/lib/faraday/response.rb +27 -16
  53. data/lib/faraday/utils/headers.rb +139 -0
  54. data/lib/faraday/utils/params_hash.rb +61 -0
  55. data/lib/faraday/utils.rb +28 -228
  56. data/lib/faraday.rb +102 -204
  57. data/spec/external_adapters/faraday_specs_setup.rb +14 -0
  58. data/spec/faraday/adapter/em_http_spec.rb +47 -0
  59. data/spec/faraday/adapter/em_synchrony_spec.rb +16 -0
  60. data/spec/faraday/adapter/excon_spec.rb +49 -0
  61. data/spec/faraday/adapter/httpclient_spec.rb +73 -0
  62. data/spec/faraday/adapter/net_http_persistent_spec.rb +57 -0
  63. data/spec/faraday/adapter/net_http_spec.rb +64 -0
  64. data/spec/faraday/adapter/patron_spec.rb +18 -0
  65. data/spec/faraday/adapter/rack_spec.rb +8 -0
  66. data/spec/faraday/adapter/typhoeus_spec.rb +7 -0
  67. data/spec/faraday/adapter_registry_spec.rb +28 -0
  68. data/spec/faraday/adapter_spec.rb +55 -0
  69. data/spec/faraday/composite_read_io_spec.rb +80 -0
  70. data/spec/faraday/connection_spec.rb +691 -0
  71. data/spec/faraday/error_spec.rb +45 -0
  72. data/spec/faraday/middleware_spec.rb +26 -0
  73. data/spec/faraday/options/env_spec.rb +70 -0
  74. data/spec/faraday/options/options_spec.rb +297 -0
  75. data/spec/faraday/options/proxy_options_spec.rb +37 -0
  76. data/spec/faraday/options/request_options_spec.rb +19 -0
  77. data/spec/faraday/params_encoders/flat_spec.rb +34 -0
  78. data/spec/faraday/params_encoders/nested_spec.rb +134 -0
  79. data/spec/faraday/rack_builder_spec.rb +196 -0
  80. data/spec/faraday/request/authorization_spec.rb +88 -0
  81. data/spec/faraday/request/instrumentation_spec.rb +76 -0
  82. data/spec/faraday/request/multipart_spec.rb +274 -0
  83. data/spec/faraday/request/retry_spec.rb +242 -0
  84. data/spec/faraday/request/url_encoded_spec.rb +70 -0
  85. data/spec/faraday/request_spec.rb +109 -0
  86. data/spec/faraday/response/logger_spec.rb +220 -0
  87. data/spec/faraday/response/middleware_spec.rb +52 -0
  88. data/spec/faraday/response/raise_error_spec.rb +106 -0
  89. data/spec/faraday/response_spec.rb +75 -0
  90. data/spec/faraday/utils/headers_spec.rb +82 -0
  91. data/spec/faraday/utils_spec.rb +56 -0
  92. data/spec/faraday_spec.rb +37 -0
  93. data/spec/spec_helper.rb +132 -0
  94. data/spec/support/disabling_stub.rb +14 -0
  95. data/spec/support/fake_safe_buffer.rb +15 -0
  96. data/spec/support/helper_methods.rb +133 -0
  97. data/spec/support/shared_examples/adapter.rb +104 -0
  98. data/spec/support/shared_examples/params_encoder.rb +18 -0
  99. data/spec/support/shared_examples/request_method.rb +234 -0
  100. data/spec/support/streaming_response_checker.rb +35 -0
  101. data/spec/support/webmock_rack_app.rb +68 -0
  102. metadata +110 -64
  103. data/lib/faraday/upload_io.rb +0 -67
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  # Subclasses Struct with some special helpers for converting from a Hash to
3
5
  # a Struct.
@@ -10,6 +12,7 @@ module Faraday
10
12
  # Public
11
13
  def each
12
14
  return to_enum(:each) unless block_given?
15
+
13
16
  members.each do |key|
14
17
  yield(key.to_sym, send(key))
15
18
  end
@@ -18,23 +21,20 @@ module Faraday
18
21
  # Public
19
22
  def update(obj)
20
23
  obj.each do |key, value|
21
- if sub_options = self.class.options_for(key)
22
- value = sub_options.from(value) if value
23
- elsif Hash === value
24
- hash = {}
25
- value.each do |hash_key, hash_value|
26
- hash[hash_key] = hash_value
27
- end
28
- value = hash
24
+ sub_options = self.class.options_for(key)
25
+ if sub_options
26
+ new_value = sub_options.from(value) if value
27
+ elsif value.is_a?(Hash)
28
+ new_value = value.dup
29
+ else
30
+ new_value = value
29
31
  end
30
32
 
31
- self.send("#{key}=", value) unless value.nil?
33
+ send("#{key}=", new_value) unless new_value.nil?
32
34
  end
33
35
  self
34
36
  end
35
37
 
36
- alias merge! update
37
-
38
38
  # Public
39
39
  def delete(key)
40
40
  value = send(key)
@@ -48,18 +48,38 @@ module Faraday
48
48
  end
49
49
 
50
50
  # Public
51
- def merge(value)
52
- dup.update(value)
51
+ def merge!(other)
52
+ other.each do |key, other_value|
53
+ self_value = send(key)
54
+ sub_options = self.class.options_for(key)
55
+ new_value = if self_value && sub_options && other_value
56
+ self_value.merge(other_value)
57
+ else
58
+ other_value
59
+ end
60
+ send("#{key}=", new_value) unless new_value.nil?
61
+ end
62
+ self
63
+ end
64
+
65
+ # Public
66
+ def merge(other)
67
+ dup.merge!(other)
68
+ end
69
+
70
+ # Public
71
+ def deep_dup
72
+ self.class.from(self)
53
73
  end
54
74
 
55
75
  # Public
56
76
  def fetch(key, *args)
57
77
  unless symbolized_key_set.include?(key.to_sym)
58
78
  key_setter = "#{key}="
59
- if args.size > 0
79
+ if !args.empty?
60
80
  send(key_setter, args.first)
61
81
  elsif block_given?
62
- send(key_setter, Proc.new.call(key))
82
+ send(key_setter, yield(key))
63
83
  else
64
84
  raise self.class.fetch_error_class, "key not found: #{key.inspect}"
65
85
  end
@@ -85,6 +105,7 @@ module Faraday
85
105
  # Public
86
106
  def each_key
87
107
  return to_enum(:each_key) unless block_given?
108
+
88
109
  keys.each do |key|
89
110
  yield(key)
90
111
  end
@@ -100,6 +121,7 @@ module Faraday
100
121
  # Public
101
122
  def each_value
102
123
  return to_enum(:each_value) unless block_given?
124
+
103
125
  values.each do |value|
104
126
  yield(value)
105
127
  end
@@ -129,9 +151,9 @@ module Faraday
129
151
  value = send(member)
130
152
  values << "#{member}=#{value.inspect}" if value
131
153
  end
132
- values = values.empty? ? ' (empty)' : (' ' << values.join(", "))
154
+ values = values.empty? ? '(empty)' : values.join(', ')
133
155
 
134
- %(#<#{self.class}#{values}>)
156
+ %(#<#{self.class} #{values}>)
135
157
  end
136
158
 
137
159
  # Internal
@@ -149,8 +171,12 @@ module Faraday
149
171
  @attribute_options ||= {}
150
172
  end
151
173
 
152
- def self.memoized(key)
153
- memoized_attributes[key.to_sym] = Proc.new
174
+ def self.memoized(key, &block)
175
+ unless block_given?
176
+ raise ArgumentError, '#memoized must be called with a block'
177
+ end
178
+
179
+ memoized_attributes[key.to_sym] = block
154
180
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
155
181
  def #{key}() self[:#{key}]; end
156
182
  RUBY
@@ -162,7 +188,7 @@ module Faraday
162
188
 
163
189
  def [](key)
164
190
  key = key.to_sym
165
- if method = self.class.memoized_attributes[key]
191
+ if (method = self.class.memoized_attributes[key])
166
192
  super(key) || (self[key] = instance_eval(&method))
167
193
  else
168
194
  super
@@ -170,7 +196,7 @@ module Faraday
170
196
  end
171
197
 
172
198
  def symbolized_key_set
173
- @symbolized_key_set ||= Set.new(keys.map { |k| k.to_sym })
199
+ @symbolized_key_set ||= Set.new(keys.map(&:to_sym))
174
200
  end
175
201
 
176
202
  def self.inherited(subclass)
@@ -181,179 +207,16 @@ module Faraday
181
207
 
182
208
  def self.fetch_error_class
183
209
  @fetch_error_class ||= if Object.const_defined?(:KeyError)
184
- ::KeyError
185
- else
186
- ::IndexError
187
- end
188
- end
189
- end
190
-
191
- class RequestOptions < Options.new(:params_encoder, :proxy, :bind,
192
- :timeout, :open_timeout, :boundary,
193
- :oauth)
194
-
195
- def []=(key, value)
196
- if key && key.to_sym == :proxy
197
- super(key, value ? ProxyOptions.from(value) : nil)
198
- else
199
- super(key, value)
200
- end
201
- end
202
- end
203
-
204
- class SSLOptions < Options.new(:verify, :ca_file, :ca_path, :verify_mode,
205
- :cert_store, :client_cert, :client_key, :certificate, :private_key, :verify_depth, :version)
206
-
207
- def verify?
208
- verify != false
209
- end
210
-
211
- def disable?
212
- !verify?
213
- end
214
- end
215
-
216
- class ProxyOptions < Options.new(:uri, :user, :password)
217
- extend Forwardable
218
- def_delegators :uri, :scheme, :scheme=, :host, :host=, :port, :port=, :path, :path=
219
-
220
- def self.from(value)
221
- case value
222
- when String
223
- value = {:uri => Utils.URI(value)}
224
- when URI
225
- value = {:uri => value}
226
- when Hash, Options
227
- if uri = value.delete(:uri)
228
- value[:uri] = Utils.URI(uri)
229
- end
230
- end
231
- super(value)
232
- end
233
-
234
- memoized(:user) { uri.user && Utils.unescape(uri.user) }
235
- memoized(:password) { uri.password && Utils.unescape(uri.password) }
236
- end
237
-
238
- class ConnectionOptions < Options.new(:request, :proxy, :ssl, :builder, :url,
239
- :parallel_manager, :params, :headers, :builder_class)
240
-
241
- options :request => RequestOptions, :ssl => SSLOptions
242
-
243
- memoized(:request) { self.class.options_for(:request).new }
244
-
245
- memoized(:ssl) { self.class.options_for(:ssl).new }
246
-
247
- memoized(:builder_class) { RackBuilder }
248
-
249
- def new_builder(block)
250
- builder_class.new(&block)
251
- end
252
- end
253
-
254
- class Env < Options.new(:method, :body, :url, :request, :request_headers,
255
- :ssl, :parallel_manager, :params, :response, :response_headers, :status)
256
-
257
- ContentLength = 'Content-Length'.freeze
258
- StatusesWithoutBody = Set.new [204, 304]
259
- SuccessfulStatuses = 200..299
260
-
261
- # A Set of HTTP verbs that typically send a body. If no body is set for
262
- # these requests, the Content-Length header is set to 0.
263
- MethodsWithBodies = Set.new [:post, :put, :patch, :options]
264
-
265
- options :request => RequestOptions,
266
- :request_headers => Utils::Headers, :response_headers => Utils::Headers
267
-
268
- extend Forwardable
269
-
270
- def_delegators :request, :params_encoder
271
-
272
- # Public
273
- def self.from(value)
274
- env = super(value)
275
- if value.respond_to?(:custom_members)
276
- env.custom_members.update(value.custom_members)
277
- end
278
- env
279
- end
280
-
281
- # Public
282
- def [](key)
283
- if in_member_set?(key)
284
- super(key)
285
- else
286
- custom_members[key]
287
- end
288
- end
289
-
290
- # Public
291
- def []=(key, value)
292
- if in_member_set?(key)
293
- super(key, value)
294
- else
295
- custom_members[key] = value
296
- end
297
- end
298
-
299
- # Public
300
- def success?
301
- SuccessfulStatuses.include?(status)
302
- end
303
-
304
- # Public
305
- def needs_body?
306
- !body && MethodsWithBodies.include?(method)
307
- end
308
-
309
- # Public
310
- def clear_body
311
- request_headers[ContentLength] = '0'
312
- self.body = ''
313
- end
314
-
315
- # Public
316
- def parse_body?
317
- !StatusesWithoutBody.include?(status)
318
- end
319
-
320
- # Public
321
- def parallel?
322
- !!parallel_manager
323
- end
324
-
325
- def inspect
326
- attrs = [nil]
327
- members.each do |mem|
328
- if value = send(mem)
329
- attrs << "@#{mem}=#{value.inspect}"
330
- end
331
- end
332
- if !custom_members.empty?
333
- attrs << "@custom=#{custom_members.inspect}"
334
- end
335
- %(#<#{self.class}#{attrs.join(" ")}>)
336
- end
337
-
338
- # Internal
339
- def custom_members
340
- @custom_members ||= {}
341
- end
342
-
343
- # Internal
344
- if members.first.is_a?(Symbol)
345
- def in_member_set?(key)
346
- self.class.member_set.include?(key.to_sym)
347
- end
348
- else
349
- def in_member_set?(key)
350
- self.class.member_set.include?(key.to_s)
351
- end
352
- end
353
-
354
- # Internal
355
- def self.member_set
356
- @member_set ||= Set.new(members)
210
+ ::KeyError
211
+ else
212
+ ::IndexError
213
+ end
357
214
  end
358
215
  end
359
216
  end
217
+
218
+ require 'faraday/options/request_options'
219
+ require 'faraday/options/ssl_options'
220
+ require 'faraday/options/proxy_options'
221
+ require 'faraday/options/connection_options'
222
+ require 'faraday/options/env'
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faraday
4
+ # Multipart value used to POST data with a content type.
5
+ class ParamPart
6
+ # @param value [String] Uploaded content as a String.
7
+ # @param content_type [String] String content type of the value.
8
+ # @param content_id [String] Optional String of this value's Content-ID.
9
+ #
10
+ # @return [Faraday::ParamPart]
11
+ def initialize(value, content_type, content_id = nil)
12
+ @value = value
13
+ @content_type = content_type
14
+ @content_id = content_id
15
+ end
16
+
17
+ # Converts this value to a form part.
18
+ #
19
+ # @param boundary [String] String multipart boundary that must not exist in
20
+ # the content exactly.
21
+ # @param key [String] String key name for this value.
22
+ #
23
+ # @return [Faraday::Parts::Part]
24
+ def to_part(boundary, key)
25
+ Faraday::Parts::Part.new(boundary, key, value, headers)
26
+ end
27
+
28
+ # Returns a Hash of String key/value pairs.
29
+ #
30
+ # @return [Hash]
31
+ def headers
32
+ {
33
+ 'Content-Type' => content_type,
34
+ 'Content-ID' => content_id
35
+ }
36
+ end
37
+
38
+ # The content to upload.
39
+ #
40
+ # @return [String]
41
+ attr_reader :value
42
+
43
+ # The value's content type.
44
+ #
45
+ # @return [String]
46
+ attr_reader :content_type
47
+
48
+ # The value's content ID, if given.
49
+ #
50
+ # @return [String, nil]
51
+ attr_reader :content_id
52
+ end
53
+ end
@@ -1,197 +1,5 @@
1
- require "forwardable"
1
+ # frozen_string_literal: true
2
2
 
3
- module Faraday
4
- module NestedParamsEncoder
5
- class << self
6
- extend Forwardable
7
- def_delegators :'Faraday::Utils', :escape, :unescape
8
- end
9
-
10
- def self.encode(params)
11
- return nil if params == nil
12
-
13
- if !params.is_a?(Array)
14
- if !params.respond_to?(:to_hash)
15
- raise TypeError,
16
- "Can't convert #{params.class} into Hash."
17
- end
18
- params = params.to_hash
19
- params = params.map do |key, value|
20
- key = key.to_s if key.kind_of?(Symbol)
21
- [key, value]
22
- end
23
- # Useful default for OAuth and caching.
24
- # Only to be used for non-Array inputs. Arrays should preserve order.
25
- params.sort!
26
- end
27
-
28
- # Helper lambda
29
- to_query = lambda do |parent, value|
30
- if value.is_a?(Hash)
31
- value = value.map do |key, val|
32
- key = escape(key)
33
- [key, val]
34
- end
35
- value.sort!
36
- buffer = ""
37
- value.each do |key, val|
38
- new_parent = "#{parent}%5B#{key}%5D"
39
- buffer << "#{to_query.call(new_parent, val)}&"
40
- end
41
- return buffer.chop
42
- elsif value.is_a?(Array)
43
- buffer = ""
44
- value.each_with_index do |val, i|
45
- new_parent = "#{parent}%5B%5D"
46
- buffer << "#{to_query.call(new_parent, val)}&"
47
- end
48
- return buffer.chop
49
- elsif value.nil?
50
- return parent
51
- else
52
- encoded_value = escape(value)
53
- return "#{parent}=#{encoded_value}"
54
- end
55
- end
56
-
57
- # The params have form [['key1', 'value1'], ['key2', 'value2']].
58
- buffer = ''
59
- params.each do |parent, value|
60
- encoded_parent = escape(parent)
61
- buffer << "#{to_query.call(encoded_parent, value)}&"
62
- end
63
- return buffer.chop
64
- end
65
-
66
- def self.decode(query)
67
- return nil if query == nil
68
-
69
- params = {}
70
- query.split("&").each do |pair|
71
- next if pair.empty?
72
- key, value = pair.split("=", 2)
73
- key = unescape(key)
74
- value = unescape(value.gsub(/\+/, ' ')) if value
75
-
76
- subkeys = key.scan(/[^\[\]]+(?:\]?\[\])?/)
77
- context = params
78
- subkeys.each_with_index do |subkey, i|
79
- is_array = subkey =~ /[\[\]]+\Z/
80
- subkey = $` if is_array
81
- last_subkey = i == subkeys.length - 1
82
-
83
- if !last_subkey || is_array
84
- value_type = is_array ? Array : Hash
85
- if context[subkey] && !context[subkey].is_a?(value_type)
86
- raise TypeError, "expected %s (got %s) for param `%s'" % [
87
- value_type.name,
88
- context[subkey].class.name,
89
- subkey
90
- ]
91
- end
92
- context = (context[subkey] ||= value_type.new)
93
- end
94
-
95
- if context.is_a?(Array) && !is_array
96
- if !context.last.is_a?(Hash) || context.last.has_key?(subkey)
97
- context << {}
98
- end
99
- context = context.last
100
- end
101
-
102
- if last_subkey
103
- if is_array
104
- context << value
105
- else
106
- context[subkey] = value
107
- end
108
- end
109
- end
110
- end
111
-
112
- dehash(params, 0)
113
- end
114
-
115
- # Internal: convert a nested hash with purely numeric keys into an array.
116
- # FIXME: this is not compatible with Rack::Utils.parse_nested_query
117
- def self.dehash(hash, depth)
118
- hash.each do |key, value|
119
- hash[key] = dehash(value, depth + 1) if value.kind_of?(Hash)
120
- end
121
-
122
- if depth > 0 && !hash.empty? && hash.keys.all? { |k| k =~ /^\d+$/ }
123
- hash.keys.sort.inject([]) { |all, key| all << hash[key] }
124
- else
125
- hash
126
- end
127
- end
128
- end
129
-
130
- module FlatParamsEncoder
131
- class << self
132
- extend Forwardable
133
- def_delegators :'Faraday::Utils', :escape, :unescape
134
- end
135
-
136
- def self.encode(params)
137
- return nil if params == nil
138
-
139
- if !params.is_a?(Array)
140
- if !params.respond_to?(:to_hash)
141
- raise TypeError,
142
- "Can't convert #{params.class} into Hash."
143
- end
144
- params = params.to_hash
145
- params = params.map do |key, value|
146
- key = key.to_s if key.kind_of?(Symbol)
147
- [key, value]
148
- end
149
- # Useful default for OAuth and caching.
150
- # Only to be used for non-Array inputs. Arrays should preserve order.
151
- params.sort!
152
- end
153
-
154
- # The params have form [['key1', 'value1'], ['key2', 'value2']].
155
- buffer = ''
156
- params.each do |key, value|
157
- encoded_key = escape(key)
158
- value = value.to_s if value == true || value == false
159
- if value == nil
160
- buffer << "#{encoded_key}&"
161
- elsif value.kind_of?(Array)
162
- value.each do |sub_value|
163
- encoded_value = escape(sub_value)
164
- buffer << "#{encoded_key}=#{encoded_value}&"
165
- end
166
- else
167
- encoded_value = escape(value)
168
- buffer << "#{encoded_key}=#{encoded_value}&"
169
- end
170
- end
171
- return buffer.chop
172
- end
173
-
174
- def self.decode(query)
175
- empty_accumulator = {}
176
- return nil if query == nil
177
- split_query = (query.split('&').map do |pair|
178
- pair.split('=', 2) if pair && !pair.empty?
179
- end).compact
180
- return split_query.inject(empty_accumulator.dup) do |accu, pair|
181
- pair[0] = unescape(pair[0])
182
- pair[1] = true if pair[1].nil?
183
- if pair[1].respond_to?(:to_str)
184
- pair[1] = unescape(pair[1].to_str.gsub(/\+/, " "))
185
- end
186
- if accu[pair[0]].kind_of?(Array)
187
- accu[pair[0]] << pair[1]
188
- elsif accu[pair[0]]
189
- accu[pair[0]] = [accu[pair[0]], pair[1]]
190
- else
191
- accu[pair[0]] = pair[1]
192
- end
193
- accu
194
- end
195
- end
196
- end
197
- end
3
+ require 'forwardable'
4
+ require 'faraday/encoders/nested_params_encoder'
5
+ require 'faraday/encoders/flat_params_encoder'