faraday 0.16.2 → 0.17.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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +1 -1
  3. data/README.md +347 -18
  4. data/lib/faraday.rb +175 -93
  5. data/lib/faraday/adapter.rb +22 -36
  6. data/lib/faraday/adapter/em_http.rb +99 -142
  7. data/lib/faraday/adapter/em_http_ssl_patch.rb +17 -23
  8. data/lib/faraday/adapter/em_synchrony.rb +60 -104
  9. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +15 -18
  10. data/lib/faraday/adapter/excon.rb +55 -100
  11. data/lib/faraday/adapter/httpclient.rb +39 -61
  12. data/lib/faraday/adapter/net_http.rb +51 -104
  13. data/lib/faraday/adapter/net_http_persistent.rb +27 -48
  14. data/lib/faraday/adapter/patron.rb +35 -54
  15. data/lib/faraday/adapter/rack.rb +12 -28
  16. data/lib/faraday/adapter/test.rb +53 -86
  17. data/lib/faraday/adapter/typhoeus.rb +1 -4
  18. data/lib/faraday/autoload.rb +36 -47
  19. data/lib/faraday/connection.rb +179 -321
  20. data/lib/faraday/error.rb +32 -80
  21. data/lib/faraday/middleware.rb +28 -4
  22. data/lib/faraday/options.rb +186 -35
  23. data/lib/faraday/parameters.rb +197 -4
  24. data/lib/faraday/rack_builder.rb +56 -67
  25. data/lib/faraday/request.rb +36 -68
  26. data/lib/faraday/request/authorization.rb +30 -42
  27. data/lib/faraday/request/basic_authentication.rb +7 -14
  28. data/lib/faraday/request/instrumentation.rb +27 -45
  29. data/lib/faraday/request/multipart.rb +48 -79
  30. data/lib/faraday/request/retry.rb +170 -197
  31. data/lib/faraday/request/token_authentication.rb +10 -15
  32. data/lib/faraday/request/url_encoded.rb +23 -41
  33. data/lib/faraday/response.rb +16 -23
  34. data/lib/faraday/response/logger.rb +69 -22
  35. data/lib/faraday/response/raise_error.rb +14 -36
  36. data/lib/faraday/upload_io.rb +67 -0
  37. data/lib/faraday/utils.rb +245 -28
  38. metadata +5 -22
  39. data/lib/faraday/adapter_registry.rb +0 -28
  40. data/lib/faraday/dependency_loader.rb +0 -37
  41. data/lib/faraday/deprecated_class.rb +0 -28
  42. data/lib/faraday/encoders/flat_params_encoder.rb +0 -94
  43. data/lib/faraday/encoders/nested_params_encoder.rb +0 -171
  44. data/lib/faraday/file_part.rb +0 -128
  45. data/lib/faraday/logging/formatter.rb +0 -92
  46. data/lib/faraday/middleware_registry.rb +0 -129
  47. data/lib/faraday/options/connection_options.rb +0 -22
  48. data/lib/faraday/options/env.rb +0 -181
  49. data/lib/faraday/options/proxy_options.rb +0 -28
  50. data/lib/faraday/options/request_options.rb +0 -21
  51. data/lib/faraday/options/ssl_options.rb +0 -59
  52. data/lib/faraday/param_part.rb +0 -53
  53. data/lib/faraday/utils/headers.rb +0 -139
  54. data/lib/faraday/utils/params_hash.rb +0 -61
  55. data/spec/external_adapters/faraday_specs_setup.rb +0 -14
@@ -1,25 +1,21 @@
1
- # frozen_string_literal: true
2
-
3
- require 'faraday/deprecated_class'
4
-
5
- # Faraday namespace.
6
1
  module Faraday
7
- # Faraday error base class.
8
- class Error < StandardError
2
+ class Error < StandardError; end
3
+
4
+ class ClientError < Error
9
5
  attr_reader :response, :wrapped_exception
10
6
 
11
- def initialize(exc, response = nil)
7
+ def initialize(ex, response = nil)
12
8
  @wrapped_exception = nil
13
9
  @response = response
14
10
 
15
- if exc.respond_to?(:backtrace)
16
- super(exc.message)
17
- @wrapped_exception = exc
18
- elsif exc.respond_to?(:each_key)
19
- super("the server responded with status #{exc[:status]}")
20
- @response = exc
11
+ if ex.respond_to?(:backtrace)
12
+ super(ex.message)
13
+ @wrapped_exception = ex
14
+ elsif ex.respond_to?(:each_key)
15
+ super("the server responded with status #{ex[:status]}")
16
+ @response = ex
21
17
  else
22
- super(exc.to_s)
18
+ super(ex.to_s)
23
19
  end
24
20
  end
25
21
 
@@ -32,83 +28,39 @@ module Faraday
32
28
  end
33
29
 
34
30
  def inspect
35
- inner = +''
36
- inner << " wrapped=#{@wrapped_exception.inspect}" if @wrapped_exception
37
- inner << " response=#{@response.inspect}" if @response
38
- inner << " #{super}" if inner.empty?
31
+ inner = ''
32
+ if @wrapped_exception
33
+ inner << " wrapped=#{@wrapped_exception.inspect}"
34
+ end
35
+ if @response
36
+ inner << " response=#{@response.inspect}"
37
+ end
38
+ if inner.empty?
39
+ inner << " #{super}"
40
+ end
39
41
  %(#<#{self.class}#{inner}>)
40
42
  end
41
43
  end
42
44
 
43
- # Faraday client error class. Represents 4xx status responses.
44
- class ClientError < Error
45
- end
46
-
47
- # Raised by Faraday::Response::RaiseError in case of a 400 response.
48
- class BadRequestError < ClientError
49
- end
45
+ class ConnectionFailed < ClientError; end
46
+ class ResourceNotFound < ClientError; end
47
+ class ParsingError < ClientError; end
50
48
 
51
- # Raised by Faraday::Response::RaiseError in case of a 401 response.
52
- class UnauthorizedError < ClientError
53
- end
54
-
55
- # Raised by Faraday::Response::RaiseError in case of a 403 response.
56
- class ForbiddenError < ClientError
57
- end
58
-
59
- # Raised by Faraday::Response::RaiseError in case of a 404 response.
60
- class ResourceNotFound < ClientError
61
- end
62
-
63
- # Raised by Faraday::Response::RaiseError in case of a 407 response.
64
- class ProxyAuthError < ClientError
65
- end
66
-
67
- # Raised by Faraday::Response::RaiseError in case of a 409 response.
68
- class ConflictError < ClientError
69
- end
70
-
71
- # Raised by Faraday::Response::RaiseError in case of a 422 response.
72
- class UnprocessableEntityError < ClientError
73
- end
74
-
75
- # Faraday server error class. Represents 5xx status responses.
76
- class ServerError < Error
77
- end
78
-
79
- # A unified client error for timeouts.
80
- class TimeoutError < ServerError
81
- def initialize(exc = 'timeout', response = nil)
82
- super(exc, response)
49
+ class TimeoutError < ClientError
50
+ def initialize(ex = nil)
51
+ super(ex || "timeout")
83
52
  end
84
53
  end
85
54
 
86
- # A unified error for failed connections.
87
- class ConnectionFailed < Error
55
+ class SSLError < ClientError
88
56
  end
89
57
 
90
- # A unified client error for SSL errors.
91
- class SSLError < Error
92
- end
58
+ class RetriableResponse < ClientError; end
93
59
 
94
- # Raised by FaradayMiddleware::ResponseMiddleware
95
- class ParsingError < Error
60
+ [:ClientError, :ConnectionFailed, :ResourceNotFound,
61
+ :ParsingError, :TimeoutError, :SSLError, :RetriableResponse].each do |const|
62
+ Error.const_set(const, Faraday.const_get(const))
96
63
  end
97
64
 
98
- # Exception used to control the Retry middleware.
99
- #
100
- # @see Faraday::Request::Retry
101
- class RetriableResponse < Error
102
- end
103
65
 
104
- %i[ClientError ConnectionFailed ResourceNotFound
105
- ParsingError TimeoutError SSLError RetriableResponse].each do |const|
106
- Error.const_set(
107
- const,
108
- Faraday::DeprecatedClass.proxy_class(
109
- "Faraday::Error::#{const}",
110
- Faraday.const_get(const)
111
- )
112
- )
113
- end
114
66
  end
@@ -1,10 +1,34 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Faraday
4
- # Middleware is the basic base class of any Faraday middleware.
5
2
  class Middleware
6
3
  extend MiddlewareRegistry
7
- extend DependencyLoader
4
+
5
+ class << self
6
+ attr_accessor :load_error
7
+ private :load_error=
8
+ end
9
+
10
+ self.load_error = nil
11
+
12
+ # Executes a block which should try to require and reference dependent libraries
13
+ def self.dependency(lib = nil)
14
+ lib ? require(lib) : yield
15
+ rescue LoadError, NameError => error
16
+ self.load_error = error
17
+ end
18
+
19
+ def self.new(*)
20
+ raise "missing dependency for #{self}: #{load_error.message}" unless loaded?
21
+ super
22
+ end
23
+
24
+ def self.loaded?
25
+ load_error.nil?
26
+ end
27
+
28
+ def self.inherited(subclass)
29
+ super
30
+ subclass.send(:load_error=, self.load_error)
31
+ end
8
32
 
9
33
  def initialize(app = nil)
10
34
  @app = app
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Faraday
4
2
  # Subclasses Struct with some special helpers for converting from a Hash to
5
3
  # a Struct.
@@ -12,7 +10,6 @@ module Faraday
12
10
  # Public
13
11
  def each
14
12
  return to_enum(:each) unless block_given?
15
-
16
13
  members.each do |key|
17
14
  yield(key.to_sym, send(key))
18
15
  end
@@ -30,7 +27,7 @@ module Faraday
30
27
  new_value = value
31
28
  end
32
29
 
33
- send("#{key}=", new_value) unless new_value.nil?
30
+ self.send("#{key}=", new_value) unless new_value.nil?
34
31
  end
35
32
  self
36
33
  end
@@ -50,14 +47,10 @@ module Faraday
50
47
  # Public
51
48
  def merge!(other)
52
49
  other.each do |key, other_value|
53
- self_value = send(key)
50
+ self_value = self.send(key)
54
51
  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?
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?
61
54
  end
62
55
  self
63
56
  end
@@ -76,10 +69,10 @@ module Faraday
76
69
  def fetch(key, *args)
77
70
  unless symbolized_key_set.include?(key.to_sym)
78
71
  key_setter = "#{key}="
79
- if !args.empty?
72
+ if args.size > 0
80
73
  send(key_setter, args.first)
81
74
  elsif block_given?
82
- send(key_setter, yield(key))
75
+ send(key_setter, Proc.new.call(key))
83
76
  else
84
77
  raise self.class.fetch_error_class, "key not found: #{key.inspect}"
85
78
  end
@@ -105,7 +98,6 @@ module Faraday
105
98
  # Public
106
99
  def each_key
107
100
  return to_enum(:each_key) unless block_given?
108
-
109
101
  keys.each do |key|
110
102
  yield(key)
111
103
  end
@@ -121,7 +113,6 @@ module Faraday
121
113
  # Public
122
114
  def each_value
123
115
  return to_enum(:each_value) unless block_given?
124
-
125
116
  values.each do |value|
126
117
  yield(value)
127
118
  end
@@ -151,9 +142,9 @@ module Faraday
151
142
  value = send(member)
152
143
  values << "#{member}=#{value.inspect}" if value
153
144
  end
154
- values = values.empty? ? '(empty)' : values.join(', ')
145
+ values = values.empty? ? ' (empty)' : (' ' << values.join(", "))
155
146
 
156
- %(#<#{self.class} #{values}>)
147
+ %(#<#{self.class}#{values}>)
157
148
  end
158
149
 
159
150
  # Internal
@@ -171,12 +162,8 @@ module Faraday
171
162
  @attribute_options ||= {}
172
163
  end
173
164
 
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
165
+ def self.memoized(key)
166
+ memoized_attributes[key.to_sym] = Proc.new
180
167
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
181
168
  def #{key}() self[:#{key}]; end
182
169
  RUBY
@@ -188,7 +175,7 @@ module Faraday
188
175
 
189
176
  def [](key)
190
177
  key = key.to_sym
191
- if (method = self.class.memoized_attributes[key])
178
+ if method = self.class.memoized_attributes[key]
192
179
  super(key) || (self[key] = instance_eval(&method))
193
180
  else
194
181
  super
@@ -196,7 +183,7 @@ module Faraday
196
183
  end
197
184
 
198
185
  def symbolized_key_set
199
- @symbolized_key_set ||= Set.new(keys.map(&:to_sym))
186
+ @symbolized_key_set ||= Set.new(keys.map { |k| k.to_sym })
200
187
  end
201
188
 
202
189
  def self.inherited(subclass)
@@ -207,16 +194,180 @@ module Faraday
207
194
 
208
195
  def self.fetch_error_class
209
196
  @fetch_error_class ||= if Object.const_defined?(:KeyError)
210
- ::KeyError
211
- else
212
- ::IndexError
213
- end
197
+ ::KeyError
198
+ else
199
+ ::IndexError
200
+ end
214
201
  end
215
202
  end
216
- end
217
203
 
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'
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)
371
+ end
372
+ end
373
+ end