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