faraday 0.15.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +570 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +25 -351
  5. data/Rakefile +7 -0
  6. data/examples/client_spec.rb +97 -0
  7. data/examples/client_test.rb +118 -0
  8. data/lib/faraday/adapter/test.rb +127 -72
  9. data/lib/faraday/adapter.rb +69 -22
  10. data/lib/faraday/adapter_registry.rb +30 -0
  11. data/lib/faraday/connection.rb +309 -232
  12. data/lib/faraday/encoders/flat_params_encoder.rb +105 -0
  13. data/lib/faraday/encoders/nested_params_encoder.rb +176 -0
  14. data/lib/faraday/error.rb +119 -38
  15. data/lib/faraday/logging/formatter.rb +106 -0
  16. data/lib/faraday/methods.rb +6 -0
  17. data/lib/faraday/middleware.rb +18 -25
  18. data/lib/faraday/middleware_registry.rb +83 -0
  19. data/lib/faraday/options/connection_options.rb +22 -0
  20. data/lib/faraday/options/env.rb +181 -0
  21. data/lib/faraday/options/proxy_options.rb +32 -0
  22. data/lib/faraday/options/request_options.rb +22 -0
  23. data/lib/faraday/options/ssl_options.rb +59 -0
  24. data/lib/faraday/options.rb +41 -195
  25. data/lib/faraday/parameters.rb +4 -196
  26. data/lib/faraday/rack_builder.rb +91 -76
  27. data/lib/faraday/request/authorization.rb +37 -29
  28. data/lib/faraday/request/instrumentation.rb +47 -27
  29. data/lib/faraday/request/json.rb +55 -0
  30. data/lib/faraday/request/url_encoded.rb +45 -23
  31. data/lib/faraday/request.rb +74 -32
  32. data/lib/faraday/response/json.rb +54 -0
  33. data/lib/faraday/response/logger.rb +22 -69
  34. data/lib/faraday/response/raise_error.rb +57 -14
  35. data/lib/faraday/response.rb +26 -33
  36. data/lib/faraday/utils/headers.rb +139 -0
  37. data/lib/faraday/utils/params_hash.rb +61 -0
  38. data/lib/faraday/utils.rb +47 -251
  39. data/lib/faraday/version.rb +5 -0
  40. data/lib/faraday.rb +108 -199
  41. data/spec/external_adapters/faraday_specs_setup.rb +14 -0
  42. data/spec/faraday/adapter/test_spec.rb +377 -0
  43. data/spec/faraday/adapter_registry_spec.rb +28 -0
  44. data/spec/faraday/adapter_spec.rb +55 -0
  45. data/spec/faraday/connection_spec.rb +787 -0
  46. data/spec/faraday/error_spec.rb +60 -0
  47. data/spec/faraday/middleware_registry_spec.rb +31 -0
  48. data/spec/faraday/middleware_spec.rb +52 -0
  49. data/spec/faraday/options/env_spec.rb +70 -0
  50. data/spec/faraday/options/options_spec.rb +297 -0
  51. data/spec/faraday/options/proxy_options_spec.rb +44 -0
  52. data/spec/faraday/options/request_options_spec.rb +19 -0
  53. data/spec/faraday/params_encoders/flat_spec.rb +42 -0
  54. data/spec/faraday/params_encoders/nested_spec.rb +142 -0
  55. data/spec/faraday/rack_builder_spec.rb +317 -0
  56. data/spec/faraday/request/authorization_spec.rb +83 -0
  57. data/spec/faraday/request/instrumentation_spec.rb +74 -0
  58. data/spec/faraday/request/json_spec.rb +111 -0
  59. data/spec/faraday/request/url_encoded_spec.rb +82 -0
  60. data/spec/faraday/request_spec.rb +109 -0
  61. data/spec/faraday/response/json_spec.rb +117 -0
  62. data/spec/faraday/response/logger_spec.rb +220 -0
  63. data/spec/faraday/response/raise_error_spec.rb +172 -0
  64. data/spec/faraday/response_spec.rb +75 -0
  65. data/spec/faraday/utils/headers_spec.rb +82 -0
  66. data/spec/faraday/utils_spec.rb +117 -0
  67. data/spec/faraday_spec.rb +37 -0
  68. data/spec/spec_helper.rb +132 -0
  69. data/spec/support/disabling_stub.rb +14 -0
  70. data/spec/support/fake_safe_buffer.rb +15 -0
  71. data/spec/support/helper_methods.rb +96 -0
  72. data/spec/support/shared_examples/adapter.rb +104 -0
  73. data/spec/support/shared_examples/params_encoder.rb +18 -0
  74. data/spec/support/shared_examples/request_method.rb +249 -0
  75. data/spec/support/streaming_response_checker.rb +35 -0
  76. metadata +86 -34
  77. data/lib/faraday/adapter/em_http.rb +0 -243
  78. data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -56
  79. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -66
  80. data/lib/faraday/adapter/em_synchrony.rb +0 -106
  81. data/lib/faraday/adapter/excon.rb +0 -79
  82. data/lib/faraday/adapter/httpclient.rb +0 -128
  83. data/lib/faraday/adapter/net_http.rb +0 -137
  84. data/lib/faraday/adapter/net_http_persistent.rb +0 -63
  85. data/lib/faraday/adapter/patron.rb +0 -100
  86. data/lib/faraday/adapter/rack.rb +0 -58
  87. data/lib/faraday/adapter/typhoeus.rb +0 -12
  88. data/lib/faraday/autoload.rb +0 -84
  89. data/lib/faraday/request/basic_authentication.rb +0 -13
  90. data/lib/faraday/request/multipart.rb +0 -68
  91. data/lib/faraday/request/retry.rb +0 -211
  92. data/lib/faraday/request/token_authentication.rb +0 -15
  93. 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
@@ -27,7 +30,7 @@ module Faraday
27
30
  new_value = value
28
31
  end
29
32
 
30
- self.send("#{key}=", new_value) unless new_value.nil?
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 = self.send(key)
53
+ self_value = send(key)
51
54
  sub_options = self.class.options_for(key)
52
- new_value = (self_value && sub_options && other_value) ? self_value.merge(other_value) : other_value
53
- self.send("#{key}=", new_value) unless new_value.nil?
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,10 +76,10 @@ 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.size > 0
79
+ if !args.empty?
73
80
  send(key_setter, args.first)
74
81
  elsif block_given?
75
- send(key_setter, Proc.new.call(key))
82
+ send(key_setter, yield(key))
76
83
  else
77
84
  raise self.class.fetch_error_class, "key not found: #{key.inspect}"
78
85
  end
@@ -96,11 +103,10 @@ module Faraday
96
103
  end
97
104
 
98
105
  # Public
99
- def each_key
100
- return to_enum(:each_key) unless block_given?
101
- keys.each do |key|
102
- yield(key)
103
- end
106
+ def each_key(&block)
107
+ return to_enum(:each_key) unless block
108
+
109
+ keys.each(&block)
104
110
  end
105
111
 
106
112
  # Public
@@ -111,11 +117,10 @@ module Faraday
111
117
  alias has_key? key?
112
118
 
113
119
  # Public
114
- def each_value
115
- return to_enum(:each_value) unless block_given?
116
- values.each do |value|
117
- yield(value)
118
- end
120
+ def each_value(&block)
121
+ return to_enum(:each_value) unless block
122
+
123
+ values.each(&block)
119
124
  end
120
125
 
121
126
  # Public
@@ -142,9 +147,9 @@ module Faraday
142
147
  value = send(member)
143
148
  values << "#{member}=#{value.inspect}" if value
144
149
  end
145
- values = values.empty? ? ' (empty)' : (' ' << values.join(", "))
150
+ values = values.empty? ? '(empty)' : values.join(', ')
146
151
 
147
- %(#<#{self.class}#{values}>)
152
+ %(#<#{self.class} #{values}>)
148
153
  end
149
154
 
150
155
  # Internal
@@ -162,8 +167,12 @@ module Faraday
162
167
  @attribute_options ||= {}
163
168
  end
164
169
 
165
- def self.memoized(key)
166
- memoized_attributes[key.to_sym] = Proc.new
170
+ def self.memoized(key, &block)
171
+ unless block
172
+ raise ArgumentError, '#memoized must be called with a block'
173
+ end
174
+
175
+ memoized_attributes[key.to_sym] = block
167
176
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
168
177
  def #{key}() self[:#{key}]; end
169
178
  RUBY
@@ -175,7 +184,7 @@ module Faraday
175
184
 
176
185
  def [](key)
177
186
  key = key.to_sym
178
- if method = self.class.memoized_attributes[key]
187
+ if (method = self.class.memoized_attributes[key])
179
188
  super(key) || (self[key] = instance_eval(&method))
180
189
  else
181
190
  super
@@ -183,7 +192,7 @@ module Faraday
183
192
  end
184
193
 
185
194
  def symbolized_key_set
186
- @symbolized_key_set ||= Set.new(keys.map { |k| k.to_sym })
195
+ @symbolized_key_set ||= Set.new(keys.map(&:to_sym))
187
196
  end
188
197
 
189
198
  def self.inherited(subclass)
@@ -194,179 +203,16 @@ module Faraday
194
203
 
195
204
  def self.fetch_error_class
196
205
  @fetch_error_class ||= if Object.const_defined?(:KeyError)
197
- ::KeyError
198
- else
199
- ::IndexError
200
- end
201
- end
202
- end
203
-
204
- class RequestOptions < Options.new(:params_encoder, :proxy, :bind,
205
- :timeout, :open_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, :version)
218
-
219
- def verify?
220
- verify != false
221
- end
222
-
223
- def disable?
224
- !verify?
225
- end
226
- end
227
-
228
- class ProxyOptions < Options.new(:uri, :user, :password)
229
- extend Forwardable
230
- def_delegators :uri, :scheme, :scheme=, :host, :host=, :port, :port=, :path, :path=
231
-
232
- def self.from(value)
233
- case value
234
- when String
235
- value = {:uri => Utils.URI(value)}
236
- when URI
237
- value = {:uri => value}
238
- when Hash, Options
239
- if uri = value.delete(:uri)
240
- value[:uri] = Utils.URI(uri)
241
- end
242
- end
243
- super(value)
244
- end
245
-
246
- memoized(:user) { uri && uri.user && Utils.unescape(uri.user) }
247
- memoized(:password) { uri && uri.password && Utils.unescape(uri.password) }
248
- end
249
-
250
- class ConnectionOptions < Options.new(:request, :proxy, :ssl, :builder, :url,
251
- :parallel_manager, :params, :headers, :builder_class)
252
-
253
- options :request => RequestOptions, :ssl => SSLOptions
254
-
255
- memoized(:request) { self.class.options_for(:request).new }
256
-
257
- memoized(:ssl) { self.class.options_for(:ssl).new }
258
-
259
- memoized(:builder_class) { RackBuilder }
260
-
261
- def new_builder(block)
262
- builder_class.new(&block)
263
- end
264
- end
265
-
266
- class Env < Options.new(:method, :body, :url, :request, :request_headers,
267
- :ssl, :parallel_manager, :params, :response, :response_headers, :status,
268
- :reason_phrase)
269
-
270
- ContentLength = 'Content-Length'.freeze
271
- StatusesWithoutBody = Set.new [204, 304]
272
- SuccessfulStatuses = 200..299
273
-
274
- # A Set of HTTP verbs that typically send a body. If no body is set for
275
- # these requests, the Content-Length header is set to 0.
276
- MethodsWithBodies = Set.new [:post, :put, :patch, :options]
277
-
278
- options :request => RequestOptions,
279
- :request_headers => Utils::Headers, :response_headers => Utils::Headers
280
-
281
- extend Forwardable
282
-
283
- def_delegators :request, :params_encoder
284
-
285
- # Public
286
- def self.from(value)
287
- env = super(value)
288
- if value.respond_to?(:custom_members)
289
- env.custom_members.update(value.custom_members)
290
- end
291
- env
292
- end
293
-
294
- # Public
295
- def [](key)
296
- if in_member_set?(key)
297
- super(key)
298
- else
299
- custom_members[key]
300
- end
301
- end
302
-
303
- # Public
304
- def []=(key, value)
305
- if in_member_set?(key)
306
- super(key, value)
307
- else
308
- custom_members[key] = value
309
- end
310
- end
311
-
312
- # Public
313
- def success?
314
- SuccessfulStatuses.include?(status)
315
- end
316
-
317
- # Public
318
- def needs_body?
319
- !body && MethodsWithBodies.include?(method)
320
- end
321
-
322
- # Public
323
- def clear_body
324
- request_headers[ContentLength] = '0'
325
- self.body = ''
326
- end
327
-
328
- # Public
329
- def parse_body?
330
- !StatusesWithoutBody.include?(status)
331
- end
332
-
333
- # Public
334
- def parallel?
335
- !!parallel_manager
336
- end
337
-
338
- def inspect
339
- attrs = [nil]
340
- members.each do |mem|
341
- if value = send(mem)
342
- attrs << "@#{mem}=#{value.inspect}"
343
- end
344
- end
345
- if !custom_members.empty?
346
- attrs << "@custom=#{custom_members.inspect}"
347
- end
348
- %(#<#{self.class}#{attrs.join(" ")}>)
349
- end
350
-
351
- # Internal
352
- def custom_members
353
- @custom_members ||= {}
354
- end
355
-
356
- # Internal
357
- if members.first.is_a?(Symbol)
358
- def in_member_set?(key)
359
- self.class.member_set.include?(key.to_sym)
360
- end
361
- else
362
- def in_member_set?(key)
363
- self.class.member_set.include?(key.to_s)
364
- end
365
- end
366
-
367
- # Internal
368
- def self.member_set
369
- @member_set ||= Set.new(members)
206
+ ::KeyError
207
+ else
208
+ ::IndexError
209
+ end
370
210
  end
371
211
  end
372
212
  end
213
+
214
+ require 'faraday/options/request_options'
215
+ require 'faraday/options/ssl_options'
216
+ require 'faraday/options/proxy_options'
217
+ require 'faraday/options/connection_options'
218
+ require 'faraday/options/env'
@@ -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'