faraday 1.9.3 → 2.6.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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +197 -3
  3. data/LICENSE.md +1 -1
  4. data/README.md +11 -9
  5. data/examples/client_spec.rb +41 -19
  6. data/examples/client_test.rb +48 -22
  7. data/lib/faraday/adapter/test.rb +43 -7
  8. data/lib/faraday/adapter.rb +4 -7
  9. data/lib/faraday/connection.rb +39 -120
  10. data/lib/faraday/encoders/nested_params_encoder.rb +13 -6
  11. data/lib/faraday/error.rb +3 -2
  12. data/lib/faraday/logging/formatter.rb +1 -0
  13. data/lib/faraday/middleware.rb +0 -1
  14. data/lib/faraday/middleware_registry.rb +17 -63
  15. data/lib/faraday/options/env.rb +18 -0
  16. data/lib/faraday/options/ssl_options.rb +11 -1
  17. data/lib/faraday/options.rb +3 -3
  18. data/lib/faraday/rack_builder.rb +23 -20
  19. data/lib/faraday/request/authorization.rb +33 -41
  20. data/lib/faraday/request/instrumentation.rb +2 -0
  21. data/lib/faraday/request/json.rb +55 -0
  22. data/lib/faraday/request/url_encoded.rb +5 -1
  23. data/lib/faraday/request.rb +12 -30
  24. data/lib/faraday/response/json.rb +54 -0
  25. data/lib/faraday/response/logger.rb +4 -4
  26. data/lib/faraday/response/raise_error.rb +9 -1
  27. data/lib/faraday/response.rb +8 -19
  28. data/lib/faraday/utils/headers.rb +1 -1
  29. data/lib/faraday/utils.rb +10 -5
  30. data/lib/faraday/version.rb +1 -1
  31. data/lib/faraday.rb +10 -44
  32. data/spec/faraday/adapter/test_spec.rb +36 -0
  33. data/spec/faraday/connection_spec.rb +148 -91
  34. data/spec/faraday/middleware_registry_spec.rb +31 -0
  35. data/spec/faraday/options/env_spec.rb +8 -2
  36. data/spec/faraday/params_encoders/nested_spec.rb +8 -0
  37. data/spec/faraday/rack_builder_spec.rb +26 -54
  38. data/spec/faraday/request/authorization_spec.rb +50 -28
  39. data/spec/faraday/request/instrumentation_spec.rb +5 -7
  40. data/spec/faraday/request/json_spec.rb +111 -0
  41. data/spec/faraday/request/url_encoded_spec.rb +12 -2
  42. data/spec/faraday/request_spec.rb +5 -15
  43. data/spec/faraday/response/json_spec.rb +117 -0
  44. data/spec/faraday/response/raise_error_spec.rb +7 -4
  45. data/spec/faraday/utils/headers_spec.rb +2 -2
  46. data/spec/faraday/utils_spec.rb +63 -1
  47. data/spec/support/fake_safe_buffer.rb +1 -1
  48. data/spec/support/helper_methods.rb +0 -37
  49. data/spec/support/shared_examples/adapter.rb +2 -2
  50. data/spec/support/shared_examples/request_method.rb +22 -21
  51. metadata +18 -149
  52. data/lib/faraday/adapter/typhoeus.rb +0 -15
  53. data/lib/faraday/autoload.rb +0 -87
  54. data/lib/faraday/dependency_loader.rb +0 -37
  55. data/lib/faraday/request/basic_authentication.rb +0 -20
  56. data/lib/faraday/request/token_authentication.rb +0 -20
  57. data/spec/faraday/adapter/em_http_spec.rb +0 -49
  58. data/spec/faraday/adapter/em_synchrony_spec.rb +0 -18
  59. data/spec/faraday/adapter/excon_spec.rb +0 -49
  60. data/spec/faraday/adapter/httpclient_spec.rb +0 -73
  61. data/spec/faraday/adapter/net_http_spec.rb +0 -64
  62. data/spec/faraday/adapter/patron_spec.rb +0 -18
  63. data/spec/faraday/adapter/rack_spec.rb +0 -8
  64. data/spec/faraday/adapter/typhoeus_spec.rb +0 -7
  65. data/spec/faraday/composite_read_io_spec.rb +0 -80
  66. data/spec/faraday/response/middleware_spec.rb +0 -68
  67. data/spec/support/webmock_rack_app.rb +0 -68
@@ -5,14 +5,9 @@ module Faraday
5
5
  # responsible for fulfilling a Faraday request.
6
6
  class Adapter
7
7
  extend MiddlewareRegistry
8
- extend DependencyLoader
9
8
 
10
9
  CONTENT_LENGTH = 'Content-Length'
11
10
 
12
- register_middleware File.expand_path('adapter', __dir__),
13
- test: [:Test, 'test'],
14
- typhoeus: [:Typhoeus, 'typhoeus']
15
-
16
11
  # This module marks an Adapter as supporting parallel requests.
17
12
  module Parallelism
18
13
  attr_writer :supports_parallel
@@ -64,7 +59,7 @@ module Faraday
64
59
 
65
60
  private
66
61
 
67
- def save_response(env, status, body, headers = nil, reason_phrase = nil)
62
+ def save_response(env, status, body, headers = nil, reason_phrase = nil, finished: true)
68
63
  env.status = status
69
64
  env.body = body
70
65
  env.reason_phrase = reason_phrase&.to_s&.strip
@@ -73,7 +68,7 @@ module Faraday
73
68
  yield(response_headers) if block_given?
74
69
  end
75
70
 
76
- env.response.finish(env) unless env.parallel?
71
+ env.response.finish(env) unless env.parallel? || !finished
77
72
  env.response
78
73
  end
79
74
 
@@ -103,3 +98,5 @@ module Faraday
103
98
  }.freeze
104
99
  end
105
100
  end
101
+
102
+ require 'faraday/adapter/test'
@@ -6,9 +6,9 @@ module Faraday
6
6
  #
7
7
  # @example
8
8
  #
9
- # conn = Faraday::Connection.new 'http://sushi.com'
9
+ # conn = Faraday::Connection.new 'http://httpbingo.org'
10
10
  #
11
- # # GET http://sushi.com/nigiri
11
+ # # GET http://httpbingo.org/nigiri
12
12
  # conn.get 'nigiri'
13
13
  # # => #<Faraday::Response>
14
14
  #
@@ -64,7 +64,7 @@ module Faraday
64
64
  options = ConnectionOptions.from(options)
65
65
 
66
66
  if url.is_a?(Hash) || url.is_a?(ConnectionOptions)
67
- options = options.merge(url)
67
+ options = Utils.deep_merge(options, url)
68
68
  url = options.url
69
69
  end
70
70
 
@@ -117,7 +117,7 @@ module Faraday
117
117
 
118
118
  extend Forwardable
119
119
 
120
- def_delegators :builder, :build, :use, :request, :response, :adapter, :app
120
+ def_delegators :builder, :use, :request, :response, :adapter, :app
121
121
 
122
122
  # Closes the underlying resources and/or connections. In the case of
123
123
  # persistent connections, this closes all currently open connections
@@ -130,10 +130,10 @@ module Faraday
130
130
  # Makes a GET HTTP request without a body.
131
131
  # @!scope class
132
132
  #
133
- # @param url [String] The optional String base URL to use as a prefix for
133
+ # @param url [String, URI, nil] The optional String base URL to use as a prefix for
134
134
  # all requests. Can also be the options Hash.
135
- # @param params [Hash] Hash of URI query unencoded key/value pairs.
136
- # @param headers [Hash] unencoded HTTP header key/value pairs.
135
+ # @param params [Hash, nil] Hash of URI query unencoded key/value pairs.
136
+ # @param headers [Hash, nil] unencoded HTTP header key/value pairs.
137
137
  #
138
138
  # @example
139
139
  # conn.get '/items', { page: 1 }, :accept => 'application/json'
@@ -152,10 +152,10 @@ module Faraday
152
152
  # Makes a HEAD HTTP request without a body.
153
153
  # @!scope class
154
154
  #
155
- # @param url [String] The optional String base URL to use as a prefix for
155
+ # @param url [String, URI, nil] The optional String base URL to use as a prefix for
156
156
  # all requests. Can also be the options Hash.
157
- # @param params [Hash] Hash of URI query unencoded key/value pairs.
158
- # @param headers [Hash] unencoded HTTP header key/value pairs.
157
+ # @param params [Hash, nil] Hash of URI query unencoded key/value pairs.
158
+ # @param headers [Hash, nil] unencoded HTTP header key/value pairs.
159
159
  #
160
160
  # @example
161
161
  # conn.head '/items/1'
@@ -167,10 +167,10 @@ module Faraday
167
167
  # Makes a DELETE HTTP request without a body.
168
168
  # @!scope class
169
169
  #
170
- # @param url [String] The optional String base URL to use as a prefix for
170
+ # @param url [String, URI, nil] The optional String base URL to use as a prefix for
171
171
  # all requests. Can also be the options Hash.
172
- # @param params [Hash] Hash of URI query unencoded key/value pairs.
173
- # @param headers [Hash] unencoded HTTP header key/value pairs.
172
+ # @param params [Hash, nil] Hash of URI query unencoded key/value pairs.
173
+ # @param headers [Hash, nil] unencoded HTTP header key/value pairs.
174
174
  #
175
175
  # @example
176
176
  # conn.delete '/items/1'
@@ -182,10 +182,10 @@ module Faraday
182
182
  # Makes a TRACE HTTP request without a body.
183
183
  # @!scope class
184
184
  #
185
- # @param url [String] The optional String base URL to use as a prefix for
185
+ # @param url [String, URI, nil] The optional String base URL to use as a prefix for
186
186
  # all requests. Can also be the options Hash.
187
- # @param params [Hash] Hash of URI query unencoded key/value pairs.
188
- # @param headers [Hash] unencoded HTTP header key/value pairs.
187
+ # @param params [Hash, nil] Hash of URI query unencoded key/value pairs.
188
+ # @param headers [Hash, nil] unencoded HTTP header key/value pairs.
189
189
  #
190
190
  # @example
191
191
  # conn.connect '/items/1'
@@ -210,9 +210,9 @@ module Faraday
210
210
  #
211
211
  # @overload options(url, params = nil, headers = nil)
212
212
  # Makes an OPTIONS HTTP request to the given URL.
213
- # @param url [String] String base URL to sue as a prefix for all requests.
214
- # @param params [Hash] Hash of URI query unencoded key/value pairs.
215
- # @param headers [Hash] unencoded HTTP header key/value pairs.
213
+ # @param url [String, URI, nil] String base URL to sue as a prefix for all requests.
214
+ # @param params [Hash, nil] Hash of URI query unencoded key/value pairs.
215
+ # @param headers [Hash, nil] unencoded HTTP header key/value pairs.
216
216
  #
217
217
  # @example
218
218
  # conn.options '/items/1'
@@ -233,10 +233,10 @@ module Faraday
233
233
  # Makes a POST HTTP request with a body.
234
234
  # @!scope class
235
235
  #
236
- # @param url [String] The optional String base URL to use as a prefix for
236
+ # @param url [String, URI, nil] The optional String base URL to use as a prefix for
237
237
  # all requests. Can also be the options Hash.
238
- # @param body [String] body for the request.
239
- # @param headers [Hash] unencoded HTTP header key/value pairs.
238
+ # @param body [String, nil] body for the request.
239
+ # @param headers [Hash, nil] unencoded HTTP header key/value pairs.
240
240
  #
241
241
  # @example
242
242
  # conn.post '/items', data, content_type: 'application/json'
@@ -255,10 +255,10 @@ module Faraday
255
255
  # Makes a PUT HTTP request with a body.
256
256
  # @!scope class
257
257
  #
258
- # @param url [String] The optional String base URL to use as a prefix for
258
+ # @param url [String, URI, nil] The optional String base URL to use as a prefix for
259
259
  # all requests. Can also be the options Hash.
260
- # @param body [String] body for the request.
261
- # @param headers [Hash] unencoded HTTP header key/value pairs.
260
+ # @param body [String, nil] body for the request.
261
+ # @param headers [Hash, nil] unencoded HTTP header key/value pairs.
262
262
  #
263
263
  # @example
264
264
  # # TODO: Make it a PUT example
@@ -283,77 +283,6 @@ module Faraday
283
283
  RUBY
284
284
  end
285
285
 
286
- # Sets up the Authorization header with these credentials, encoded
287
- # with base64.
288
- #
289
- # @param login [String] The authentication login.
290
- # @param pass [String] The authentication password.
291
- #
292
- # @example
293
- #
294
- # conn.basic_auth 'Aladdin', 'open sesame'
295
- # conn.headers['Authorization']
296
- # # => "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="
297
- #
298
- # @return [void]
299
- def basic_auth(login, pass)
300
- warn <<~TEXT
301
- WARNING: `Faraday::Connection#basic_auth` is deprecated; it will be removed in version 2.0.
302
- While initializing your connection, use `#request(:basic_auth, ...)` instead.
303
- See https://lostisland.github.io/faraday/middleware/authentication for more usage info.
304
- TEXT
305
- set_authorization_header(:basic_auth, login, pass)
306
- end
307
-
308
- # Sets up the Authorization header with the given token.
309
- #
310
- # @param token [String]
311
- # @param options [Hash] extra token options.
312
- #
313
- # @example
314
- #
315
- # conn.token_auth 'abcdef', foo: 'bar'
316
- # conn.headers['Authorization']
317
- # # => "Token token=\"abcdef\",
318
- # foo=\"bar\""
319
- #
320
- # @return [void]
321
- def token_auth(token, options = nil)
322
- warn <<~TEXT
323
- WARNING: `Faraday::Connection#token_auth` is deprecated; it will be removed in version 2.0.
324
- While initializing your connection, use `#request(:token_auth, ...)` instead.
325
- See https://lostisland.github.io/faraday/middleware/authentication for more usage info.
326
- TEXT
327
- set_authorization_header(:token_auth, token, options)
328
- end
329
-
330
- # Sets up a custom Authorization header.
331
- #
332
- # @param type [String] authorization type
333
- # @param token [String, Hash] token. A String value is taken literally, and
334
- # a Hash is encoded into comma-separated key/value pairs.
335
- #
336
- # @example
337
- #
338
- # conn.authorization :Bearer, 'mF_9.B5f-4.1JqM'
339
- # conn.headers['Authorization']
340
- # # => "Bearer mF_9.B5f-4.1JqM"
341
- #
342
- # conn.authorization :Token, token: 'abcdef', foo: 'bar'
343
- # conn.headers['Authorization']
344
- # # => "Token token=\"abcdef\",
345
- # foo=\"bar\""
346
- #
347
- # @return [void]
348
- def authorization(type, token)
349
- warn <<~TEXT
350
- WARNING: `Faraday::Connection#authorization` is deprecated; it will be removed in version 2.0.
351
- While initializing your connection, use `#request(:authorization, ...)` instead.
352
- See https://lostisland.github.io/faraday/middleware/authentication for more usage info.
353
- TEXT
354
- set_authorization_header(:authorization, type, token)
355
- end
356
-
357
286
  # Check if the adapter is parallel-capable.
358
287
  #
359
288
  # @yield if the adapter isn't parallel-capable, or if no adapter is set yet.
@@ -420,11 +349,11 @@ module Faraday
420
349
  # @example
421
350
  #
422
351
  # conn = Faraday::Connection.new { ... }
423
- # conn.url_prefix = "https://sushi.com/api"
352
+ # conn.url_prefix = "https://httpbingo.org/api"
424
353
  # conn.scheme # => https
425
354
  # conn.path_prefix # => "/api"
426
355
  #
427
- # conn.get("nigiri?page=2") # accesses https://sushi.com/api/nigiri
356
+ # conn.get("nigiri?page=2") # accesses https://httpbingo.org/api/nigiri
428
357
  def url_prefix=(url, encoder = nil)
429
358
  uri = @url_prefix = Utils.URI(url)
430
359
  self.path_prefix = uri.path
@@ -441,7 +370,7 @@ module Faraday
441
370
  end
442
371
 
443
372
  def set_basic_auth(user, password)
444
- header = Faraday::Request::BasicAuthentication.header(user, password)
373
+ header = Faraday::Utils.basic_header_from(user, password)
445
374
  headers[Faraday::Request::Authorization::KEY] = header
446
375
  end
447
376
 
@@ -461,20 +390,20 @@ module Faraday
461
390
  # Takes a relative url for a request and combines it with the defaults
462
391
  # set on the connection instance.
463
392
  #
464
- # @param url [String]
393
+ # @param url [String, URI, nil]
465
394
  # @param extra_params [Hash]
466
395
  #
467
396
  # @example
468
397
  # conn = Faraday::Connection.new { ... }
469
- # conn.url_prefix = "https://sushi.com/api?token=abc"
398
+ # conn.url_prefix = "https://httpbingo.org/api?token=abc"
470
399
  # conn.scheme # => https
471
400
  # conn.path_prefix # => "/api"
472
401
  #
473
402
  # conn.build_url("nigiri?page=2")
474
- # # => https://sushi.com/api/nigiri?token=abc&page=2
403
+ # # => https://httpbingo.org/api/nigiri?token=abc&page=2
475
404
  #
476
405
  # conn.build_url("nigiri", page: 2)
477
- # # => https://sushi.com/api/nigiri?token=abc&page=2
406
+ # # => https://httpbingo.org/api/nigiri?token=abc&page=2
478
407
  #
479
408
  def build_url(url = nil, extra_params = nil)
480
409
  uri = build_exclusive_url(url)
@@ -494,10 +423,10 @@ module Faraday
494
423
  # Builds and runs the Faraday::Request.
495
424
  #
496
425
  # @param method [Symbol] HTTP method.
497
- # @param url [String, URI] String or URI to access.
498
- # @param body [Object] The request body that will eventually be converted to
426
+ # @param url [String, URI, nil] String or URI to access.
427
+ # @param body [String, nil] The request body that will eventually be converted to
499
428
  # a string.
500
- # @param headers [Hash] unencoded HTTP header key/value pairs.
429
+ # @param headers [Hash, nil] unencoded HTTP header key/value pairs.
501
430
  #
502
431
  # @return [Faraday::Response]
503
432
  def run_request(method, url, body, headers)
@@ -533,7 +462,7 @@ module Faraday
533
462
 
534
463
  # Build an absolute URL based on url_prefix.
535
464
  #
536
- # @param url [String, URI]
465
+ # @param url [String, URI, nil]
537
466
  # @param params [Faraday::Utils::ParamsHash] A Faraday::Utils::ParamsHash to
538
467
  # replace the query values
539
468
  # of the resulting url (default: nil).
@@ -545,14 +474,12 @@ module Faraday
545
474
  if url && base.path && base.path !~ %r{/$}
546
475
  base.path = "#{base.path}/" # ensure trailing slash
547
476
  end
548
- url = url && URI.parse(url.to_s).opaque ? url.to_s.gsub(':', '%3A') : url
477
+ url = url.to_s.gsub(':', '%3A') if url && URI.parse(url.to_s).opaque
549
478
  uri = url ? base + url : base
550
479
  if params
551
480
  uri.query = params.to_query(params_encoder || options.params_encoder)
552
481
  end
553
- # rubocop:disable Style/SafeNavigation
554
482
  uri.query = nil if uri.query && uri.query.empty?
555
- # rubocop:enable Style/SafeNavigation
556
483
  uri
557
484
  end
558
485
 
@@ -584,14 +511,6 @@ module Faraday
584
511
  yield(Utils.unescape(uri.user), Utils.unescape(uri.password))
585
512
  end
586
513
 
587
- def set_authorization_header(header_type, *args)
588
- header = Faraday::Request
589
- .lookup_middleware(header_type)
590
- .header(*args)
591
-
592
- headers[Faraday::Request::Authorization::KEY] = header
593
- end
594
-
595
514
  def proxy_from_env(url)
596
515
  return if Faraday.ignore_env_proxy
597
516
 
@@ -618,7 +537,7 @@ module Faraday
618
537
  end
619
538
 
620
539
  def find_default_proxy
621
- uri = ENV['http_proxy']
540
+ uri = ENV.fetch('http_proxy', nil)
622
541
  return unless uri && !uri.empty?
623
542
 
624
543
  uri = "http://#{uri}" unless uri.match?(/^http/i)
@@ -636,7 +555,7 @@ module Faraday
636
555
  end
637
556
 
638
557
  def support_parallel?(adapter)
639
- adapter&.respond_to?(:supports_parallel?) && adapter&.supports_parallel?
558
+ adapter.respond_to?(:supports_parallel?) && adapter&.supports_parallel?
640
559
  end
641
560
  end
642
561
  end
@@ -62,11 +62,17 @@ module Faraday
62
62
  end
63
63
 
64
64
  def encode_array(parent, value)
65
- new_parent = "#{parent}%5B%5D"
66
- return new_parent if value.empty?
65
+ return "#{parent}%5B%5D" if value.empty?
67
66
 
68
67
  buffer = +''
69
- value.each { |val| buffer << "#{encode_pair(new_parent, val)}&" }
68
+ value.each_with_index do |val, index|
69
+ new_parent = if @array_indices
70
+ "#{parent}%5B#{index}%5D"
71
+ else
72
+ "#{parent}%5B%5D"
73
+ end
74
+ buffer << "#{encode_pair(new_parent, val)}&"
75
+ end
70
76
  buffer.chop
71
77
  end
72
78
  end
@@ -102,7 +108,7 @@ module Faraday
102
108
  subkeys = key.scan(SUBKEYS_REGEX)
103
109
  subkeys.each_with_index do |subkey, i|
104
110
  is_array = subkey =~ /[\[\]]+\Z/
105
- subkey = $` if is_array
111
+ subkey = Regexp.last_match.pre_match if is_array
106
112
  last_subkey = i == subkeys.length - 1
107
113
 
108
114
  context = prepare_context(context, subkey, is_array, last_subkey)
@@ -124,7 +130,7 @@ module Faraday
124
130
  value_type = is_array ? Array : Hash
125
131
  if context[subkey] && !context[subkey].is_a?(value_type)
126
132
  raise TypeError, "expected #{value_type.name} " \
127
- "(got #{context[subkey].class.name}) for param `#{subkey}'"
133
+ "(got #{context[subkey].class.name}) for param `#{subkey}'"
128
134
  end
129
135
 
130
136
  context[subkey] ||= value_type.new
@@ -161,7 +167,7 @@ module Faraday
161
167
  # for your requests.
162
168
  module NestedParamsEncoder
163
169
  class << self
164
- attr_accessor :sort_params
170
+ attr_accessor :sort_params, :array_indices
165
171
 
166
172
  extend Forwardable
167
173
  def_delegators :'Faraday::Utils', :escape, :unescape
@@ -169,6 +175,7 @@ module Faraday
169
175
 
170
176
  # Useful default for OAuth and caching.
171
177
  @sort_params = true
178
+ @array_indices = false
172
179
 
173
180
  extend EncodeMethods
174
181
  extend DecodeMethods
data/lib/faraday/error.rb CHANGED
@@ -6,7 +6,7 @@ module Faraday
6
6
  class Error < StandardError
7
7
  attr_reader :response, :wrapped_exception
8
8
 
9
- def initialize(exc, response = nil)
9
+ def initialize(exc = nil, response = nil)
10
10
  @wrapped_exception = nil unless defined?(@wrapped_exception)
11
11
  @response = nil unless defined?(@response)
12
12
  super(exc_msg_and_response!(exc, response))
@@ -52,6 +52,7 @@ module Faraday
52
52
  # :body - Optional string HTTP response body.
53
53
  # :request - Hash
54
54
  # :method - Symbol with the request HTTP method.
55
+ # :url - URI object with the url requested.
55
56
  # :url_path - String with the url path requested.
56
57
  # :params - String key/value hash of query params
57
58
  # present in the request.
@@ -140,7 +141,7 @@ module Faraday
140
141
  class SSLError < Error
141
142
  end
142
143
 
143
- # Raised by FaradayMiddleware::ResponseMiddleware
144
+ # Raised by middlewares that parse the response, like the JSON response middleware.
144
145
  class ParsingError < Error
145
146
  end
146
147
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'pp'
4
+
4
5
  module Faraday
5
6
  module Logging
6
7
  # Serves as an integration point to customize logging
@@ -4,7 +4,6 @@ module Faraday
4
4
  # Middleware is the basic base class of any Faraday middleware.
5
5
  class Middleware
6
6
  extend MiddlewareRegistry
7
- extend DependencyLoader
8
7
 
9
8
  attr_reader :app, :options
10
9
 
@@ -6,59 +6,26 @@ module Faraday
6
6
  # Adds the ability for other modules to register and lookup
7
7
  # middleware classes.
8
8
  module MiddlewareRegistry
9
+ def registered_middleware
10
+ @registered_middleware ||= {}
11
+ end
12
+
9
13
  # Register middleware class(es) on the current module.
10
14
  #
11
- # @param autoload_path [String] Middleware autoload path
12
- # @param mapping [Hash{
13
- # Symbol => Module,
14
- # Symbol => Array<Module, Symbol, String>,
15
- # }] Middleware mapping from a lookup symbol to a reference to the
16
- # middleware.
17
- # Classes can be expressed as:
18
- # - a fully qualified constant
19
- # - a Symbol
20
- # - a Proc that will be lazily called to return the former
21
- # - an array is given, its first element is the constant or symbol,
22
- # and its second is a file to `require`.
15
+ # @param mappings [Hash] Middleware mappings from a lookup symbol to a middleware class.
23
16
  # @return [void]
24
17
  #
25
18
  # @example Lookup by a constant
26
19
  #
27
20
  # module Faraday
28
- # class Whatever
21
+ # class Whatever < Middleware
29
22
  # # Middleware looked up by :foo returns Faraday::Whatever::Foo.
30
- # register_middleware foo: Foo
31
- # end
32
- # end
33
- #
34
- # @example Lookup by a symbol
35
- #
36
- # module Faraday
37
- # class Whatever
38
- # # Middleware looked up by :bar returns
39
- # # Faraday::Whatever.const_get(:Bar)
40
- # register_middleware bar: :Bar
41
- # end
42
- # end
43
- #
44
- # @example Lookup by a symbol and string in an array
45
- #
46
- # module Faraday
47
- # class Whatever
48
- # # Middleware looked up by :baz requires 'baz' and returns
49
- # # Faraday::Whatever.const_get(:Baz)
50
- # register_middleware baz: [:Baz, 'baz']
23
+ # register_middleware(foo: Whatever)
51
24
  # end
52
25
  # end
53
- #
54
- def register_middleware(autoload_path = nil, mapping = nil)
55
- if mapping.nil?
56
- mapping = autoload_path
57
- autoload_path = nil
58
- end
26
+ def register_middleware(**mappings)
59
27
  middleware_mutex do
60
- @middleware_autoload_path = autoload_path if autoload_path
61
- (@registered_middleware ||= {}).update(mapping)
28
+ registered_middleware.update(mappings)
62
29
  end
63
30
  end
64
31
 
@@ -66,7 +33,7 @@ module Faraday
66
33
  #
67
34
  # @param key [Symbol] key for the registered middleware.
68
35
  def unregister_middleware(key)
69
- @registered_middleware.delete(key)
36
+ registered_middleware.delete(key)
70
37
  end
71
38
 
72
39
  # Lookup middleware class with a registered Symbol shortcut.
@@ -78,30 +45,27 @@ module Faraday
78
45
  # @example
79
46
  #
80
47
  # module Faraday
81
- # class Whatever
82
- # register_middleware foo: Foo
48
+ # class Whatever < Middleware
49
+ # register_middleware(foo: Whatever)
83
50
  # end
84
51
  # end
85
52
  #
86
- # Faraday::Whatever.lookup_middleware(:foo)
87
- # # => Faraday::Whatever::Foo
88
- #
53
+ # Faraday::Middleware.lookup_middleware(:foo)
54
+ # # => Faraday::Whatever
89
55
  def lookup_middleware(key)
90
56
  load_middleware(key) ||
91
57
  raise(Faraday::Error, "#{key.inspect} is not registered on #{self}")
92
58
  end
93
59
 
60
+ private
61
+
94
62
  def middleware_mutex(&block)
95
63
  @middleware_mutex ||= Monitor.new
96
64
  @middleware_mutex.synchronize(&block)
97
65
  end
98
66
 
99
- def fetch_middleware(key)
100
- defined?(@registered_middleware) && @registered_middleware[key]
101
- end
102
-
103
67
  def load_middleware(key)
104
- value = fetch_middleware(key)
68
+ value = registered_middleware[key]
105
69
  case value
106
70
  when Module
107
71
  value
@@ -113,16 +77,6 @@ module Faraday
113
77
  middleware_mutex do
114
78
  @registered_middleware[key] = value.call
115
79
  end
116
- when Array
117
- middleware_mutex do
118
- const, path = value
119
- if (root = @middleware_autoload_path)
120
- path = "#{root}/#{path}"
121
- end
122
- require(path)
123
- @registered_middleware[key] = const
124
- end
125
- load_middleware(key)
126
80
  end
127
81
  end
128
82
  end
@@ -157,6 +157,24 @@ module Faraday
157
157
  %(#<#{self.class}#{attrs.join(' ')}>)
158
158
  end
159
159
 
160
+ def stream_response?
161
+ request.stream_response?
162
+ end
163
+
164
+ def stream_response(&block)
165
+ size = 0
166
+ yielded = false
167
+ block_result = block.call do |chunk| # rubocop:disable Performance/RedundantBlockCall
168
+ if chunk.bytesize.positive? || size.positive?
169
+ yielded = true
170
+ size += chunk.bytesize
171
+ request.on_data.call(chunk, size, self)
172
+ end
173
+ end
174
+ request.on_data.call(+'', 0, self) unless yielded
175
+ block_result
176
+ end
177
+
160
178
  # @private
161
179
  def custom_members
162
180
  @custom_members ||= {}
@@ -6,6 +6,10 @@ module Faraday
6
6
  # @!attribute verify
7
7
  # @return [Boolean] whether to verify SSL certificates or not
8
8
  #
9
+ # @!attribute verify_hostname
10
+ # @return [Boolean] whether to enable hostname verification on server certificates
11
+ # during the handshake or not (see https://github.com/ruby/openssl/pull/60)
12
+ #
9
13
  # @!attribute ca_file
10
14
  # @return [String] CA file
11
15
  #
@@ -41,7 +45,8 @@ module Faraday
41
45
  #
42
46
  # @!attribute max_version
43
47
  # @return [String, Symbol] maximum SSL version (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html#method-i-max_version-3D)
44
- class SSLOptions < Options.new(:verify, :ca_file, :ca_path, :verify_mode,
48
+ class SSLOptions < Options.new(:verify, :verify_hostname,
49
+ :ca_file, :ca_path, :verify_mode,
45
50
  :cert_store, :client_cert, :client_key,
46
51
  :certificate, :private_key, :verify_depth,
47
52
  :version, :min_version, :max_version)
@@ -55,5 +60,10 @@ module Faraday
55
60
  def disable?
56
61
  !verify?
57
62
  end
63
+
64
+ # @return [Boolean] true if should verify_hostname
65
+ def verify_hostname?
66
+ verify_hostname != false
67
+ end
58
68
  end
59
69
  end
@@ -104,7 +104,7 @@ module Faraday
104
104
 
105
105
  # Public
106
106
  def each_key(&block)
107
- return to_enum(:each_key) unless block_given?
107
+ return to_enum(:each_key) unless block
108
108
 
109
109
  keys.each(&block)
110
110
  end
@@ -118,7 +118,7 @@ module Faraday
118
118
 
119
119
  # Public
120
120
  def each_value(&block)
121
- return to_enum(:each_value) unless block_given?
121
+ return to_enum(:each_value) unless block
122
122
 
123
123
  values.each(&block)
124
124
  end
@@ -168,7 +168,7 @@ module Faraday
168
168
  end
169
169
 
170
170
  def self.memoized(key, &block)
171
- unless block_given?
171
+ unless block
172
172
  raise ArgumentError, '#memoized must be called with a block'
173
173
  end
174
174