faraday 1.10.0 → 2.7.10

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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +197 -3
  3. data/LICENSE.md +1 -1
  4. data/README.md +20 -17
  5. data/Rakefile +3 -1
  6. data/examples/client_spec.rb +41 -19
  7. data/examples/client_test.rb +48 -22
  8. data/lib/faraday/adapter/test.rb +61 -12
  9. data/lib/faraday/adapter.rb +5 -9
  10. data/lib/faraday/connection.rb +58 -145
  11. data/lib/faraday/encoders/nested_params_encoder.rb +13 -6
  12. data/lib/faraday/error.rb +16 -5
  13. data/lib/faraday/logging/formatter.rb +27 -14
  14. data/lib/faraday/middleware.rb +3 -1
  15. data/lib/faraday/middleware_registry.rb +17 -63
  16. data/lib/faraday/options/connection_options.rb +7 -6
  17. data/lib/faraday/options/env.rb +85 -62
  18. data/lib/faraday/options/proxy_options.rb +7 -3
  19. data/lib/faraday/options/request_options.rb +7 -6
  20. data/lib/faraday/options/ssl_options.rb +56 -45
  21. data/lib/faraday/options.rb +4 -3
  22. data/lib/faraday/rack_builder.rb +23 -20
  23. data/lib/faraday/request/authorization.rb +33 -41
  24. data/lib/faraday/request/instrumentation.rb +5 -1
  25. data/lib/faraday/request/json.rb +10 -1
  26. data/lib/faraday/request/url_encoded.rb +5 -1
  27. data/lib/faraday/request.rb +15 -31
  28. data/lib/faraday/response/json.rb +4 -4
  29. data/lib/faraday/response/logger.rb +6 -0
  30. data/lib/faraday/response/raise_error.rb +11 -1
  31. data/lib/faraday/response.rb +9 -21
  32. data/lib/faraday/utils/headers.rb +7 -2
  33. data/lib/faraday/utils.rb +10 -5
  34. data/lib/faraday/version.rb +1 -1
  35. data/lib/faraday.rb +8 -44
  36. data/spec/faraday/adapter/test_spec.rb +65 -0
  37. data/spec/faraday/connection_spec.rb +163 -91
  38. data/spec/faraday/error_spec.rb +31 -6
  39. data/spec/faraday/middleware_registry_spec.rb +31 -0
  40. data/spec/faraday/middleware_spec.rb +18 -0
  41. data/spec/faraday/options/env_spec.rb +8 -2
  42. data/spec/faraday/options/options_spec.rb +1 -1
  43. data/spec/faraday/options/proxy_options_spec.rb +8 -0
  44. data/spec/faraday/params_encoders/nested_spec.rb +8 -0
  45. data/spec/faraday/rack_builder_spec.rb +26 -54
  46. data/spec/faraday/request/authorization_spec.rb +50 -28
  47. data/spec/faraday/request/instrumentation_spec.rb +5 -7
  48. data/spec/faraday/request/json_spec.rb +24 -0
  49. data/spec/faraday/request/url_encoded_spec.rb +12 -2
  50. data/spec/faraday/request_spec.rb +5 -15
  51. data/spec/faraday/response/json_spec.rb +4 -6
  52. data/spec/faraday/response/logger_spec.rb +38 -0
  53. data/spec/faraday/response/raise_error_spec.rb +19 -4
  54. data/spec/faraday/response_spec.rb +3 -1
  55. data/spec/faraday/utils/headers_spec.rb +22 -4
  56. data/spec/faraday/utils_spec.rb +63 -1
  57. data/spec/support/fake_safe_buffer.rb +1 -1
  58. data/spec/support/helper_methods.rb +0 -37
  59. data/spec/support/shared_examples/adapter.rb +2 -2
  60. data/spec/support/shared_examples/request_method.rb +22 -21
  61. metadata +14 -149
  62. data/lib/faraday/adapter/typhoeus.rb +0 -15
  63. data/lib/faraday/autoload.rb +0 -87
  64. data/lib/faraday/dependency_loader.rb +0 -37
  65. data/lib/faraday/request/basic_authentication.rb +0 -20
  66. data/lib/faraday/request/token_authentication.rb +0 -20
  67. data/spec/faraday/adapter/em_http_spec.rb +0 -49
  68. data/spec/faraday/adapter/em_synchrony_spec.rb +0 -18
  69. data/spec/faraday/adapter/excon_spec.rb +0 -49
  70. data/spec/faraday/adapter/httpclient_spec.rb +0 -73
  71. data/spec/faraday/adapter/net_http_spec.rb +0 -64
  72. data/spec/faraday/adapter/patron_spec.rb +0 -18
  73. data/spec/faraday/adapter/rack_spec.rb +0 -8
  74. data/spec/faraday/adapter/typhoeus_spec.rb +0 -7
  75. data/spec/faraday/composite_read_io_spec.rb +0 -80
  76. data/spec/faraday/response/middleware_spec.rb +0 -68
  77. data/spec/support/webmock_rack_app.rb +0 -68
@@ -8,7 +8,7 @@ module Faraday
8
8
  # middleware stack (heavily inspired by Rack).
9
9
  #
10
10
  # @example
11
- # Faraday::Connection.new(url: 'http://sushi.com') do |builder|
11
+ # Faraday::Connection.new(url: 'http://httpbingo.org') do |builder|
12
12
  # builder.request :url_encoded # Faraday::Request::UrlEncoded
13
13
  # builder.adapter :net_http # Faraday::Adapter::NetHttp
14
14
  # end
@@ -58,23 +58,22 @@ module Faraday
58
58
  end
59
59
  end
60
60
 
61
- def initialize(handlers = [], adapter = nil, &block)
62
- @adapter = adapter
63
- @handlers = handlers
64
- if block_given?
65
- build(&block)
66
- elsif @handlers.empty?
67
- # default stack, if nothing else is configured
68
- request :url_encoded
69
- self.adapter Faraday.default_adapter
70
- end
61
+ def initialize(&block)
62
+ @adapter = nil
63
+ @handlers = []
64
+ build(&block)
65
+ end
66
+
67
+ def initialize_dup(original)
68
+ super
69
+ @adapter = original.adapter
70
+ @handlers = original.handlers.dup
71
71
  end
72
72
 
73
- def build(options = {})
73
+ def build
74
74
  raise_if_locked
75
- @handlers.clear unless options[:keep]
76
- yield(self) if block_given?
77
- adapter(Faraday.default_adapter) unless @adapter
75
+ block_given? ? yield(self) : request(:url_encoded)
76
+ adapter(Faraday.default_adapter, **Faraday.default_adapter_options) unless @adapter
78
77
  end
79
78
 
80
79
  def [](idx)
@@ -109,7 +108,7 @@ module Faraday
109
108
  end
110
109
 
111
110
  ruby2_keywords def adapter(klass = NO_ARGUMENT, *args, &block)
112
- return @adapter if klass == NO_ARGUMENT
111
+ return @adapter if klass == NO_ARGUMENT || klass.nil?
113
112
 
114
113
  klass = Faraday::Adapter.lookup_middleware(klass) if klass.is_a?(Symbol)
115
114
  @adapter = self.class::Handler.new(klass, *args, &block)
@@ -164,6 +163,7 @@ module Faraday
164
163
  def app
165
164
  @app ||= begin
166
165
  lock!
166
+ ensure_adapter!
167
167
  to_app
168
168
  end
169
169
  end
@@ -182,10 +182,6 @@ module Faraday
182
182
  @adapter == other.adapter
183
183
  end
184
184
 
185
- def dup
186
- self.class.new(@handlers.dup, @adapter.dup)
187
- end
188
-
189
185
  # ENV Keys
190
186
  # :http_method - a symbolized request HTTP method (:get, :post)
191
187
  # :body - the request body that will eventually be converted to a string.
@@ -216,6 +212,9 @@ module Faraday
216
212
  private
217
213
 
218
214
  LOCK_ERR = "can't modify middleware stack after making a request"
215
+ MISSING_ADAPTER_ERROR = "An attempt to run a request with a Faraday::Connection without adapter has been made.\n" \
216
+ "Please set Faraday.default_adapter or provide one when initializing the connection.\n" \
217
+ 'For more info, check https://lostisland.github.io/faraday/usage/.'
219
218
 
220
219
  def raise_if_locked
221
220
  raise StackLocked, LOCK_ERR if locked?
@@ -227,6 +226,10 @@ module Faraday
227
226
  raise 'Adapter should be set using the `adapter` method, not `use`'
228
227
  end
229
228
 
229
+ def ensure_adapter!
230
+ raise MISSING_ADAPTER_ERROR unless @adapter
231
+ end
232
+
230
233
  def adapter_set?
231
234
  !@adapter.nil?
232
235
  end
@@ -1,53 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'base64'
4
-
5
3
  module Faraday
6
4
  class Request
7
5
  # Request middleware for the Authorization HTTP header
8
6
  class Authorization < Faraday::Middleware
9
- unless defined?(::Faraday::Request::Authorization::KEY)
10
- KEY = 'Authorization'
11
- end
12
-
13
- # @param type [String, Symbol]
14
- # @param token [String, Symbol, Hash]
15
- # @return [String] a header value
16
- def self.header(type, token)
17
- case token
18
- when String, Symbol, Proc
19
- token = token.call if token.is_a?(Proc)
20
- "#{type} #{token}"
21
- when Hash
22
- build_hash(type.to_s, token)
23
- else
24
- raise ArgumentError,
25
- "Can't build an Authorization #{type}" \
26
- "header from #{token.inspect}"
27
- end
28
- end
29
-
30
- # @param type [String]
31
- # @param hash [Hash]
32
- # @return [String] type followed by comma-separated key=value pairs
33
- # @api private
34
- def self.build_hash(type, hash)
35
- comma = ', '
36
- values = []
37
- hash.each do |key, value|
38
- value = value.call if value.is_a?(Proc)
39
- values << "#{key}=#{value.to_s.inspect}"
40
- end
41
- "#{type} #{values * comma}"
42
- end
7
+ KEY = 'Authorization'
43
8
 
44
9
  # @param app [#call]
45
10
  # @param type [String, Symbol] Type of Authorization
46
- # @param param [String, Symbol, Hash, Proc] parameter to build the Authorization header.
47
- # This value can be a proc, in which case it will be invoked on each request.
48
- def initialize(app, type, param)
11
+ # @param params [Array<String, Proc, #call>] parameters to build the Authorization header.
12
+ # If the type is `:basic`, then these can be a login and password pair.
13
+ # Otherwise, a single value is expected that will be appended after the type.
14
+ # This value can be a proc or an object responding to `.call`, in which case
15
+ # it will be invoked on each request.
16
+ def initialize(app, type, *params)
49
17
  @type = type
50
- @param = param
18
+ @params = params
51
19
  super(app)
52
20
  end
53
21
 
@@ -55,8 +23,32 @@ module Faraday
55
23
  def on_request(env)
56
24
  return if env.request_headers[KEY]
57
25
 
58
- env.request_headers[KEY] = self.class.header(@type, @param)
26
+ env.request_headers[KEY] = header_from(@type, env, *@params)
27
+ end
28
+
29
+ private
30
+
31
+ # @param type [String, Symbol]
32
+ # @param env [Faraday::Env]
33
+ # @param params [Array]
34
+ # @return [String] a header value
35
+ def header_from(type, env, *params)
36
+ if type.to_s.casecmp('basic').zero? && params.size == 2
37
+ Utils.basic_header_from(*params)
38
+ elsif params.size != 1
39
+ raise ArgumentError, "Unexpected params received (got #{params.size} instead of 1)"
40
+ else
41
+ value = params.first
42
+ if (value.is_a?(Proc) && value.arity == 1) || (value.respond_to?(:call) && value.method(:call).arity == 1)
43
+ value = value.call(env)
44
+ elsif value.is_a?(Proc) || value.respond_to?(:call)
45
+ value = value.call
46
+ end
47
+ "#{type} #{value}"
48
+ end
59
49
  end
60
50
  end
61
51
  end
62
52
  end
53
+
54
+ Faraday::Request.register_middleware(authorization: Faraday::Request::Authorization)
@@ -5,12 +5,14 @@ module Faraday
5
5
  # Middleware for instrumenting Requests.
6
6
  class Instrumentation < Faraday::Middleware
7
7
  # Options class used in Request::Instrumentation class.
8
- class Options < Faraday::Options.new(:name, :instrumenter)
8
+ Options = Faraday::Options.new(:name, :instrumenter) do
9
+ remove_method :name
9
10
  # @return [String]
10
11
  def name
11
12
  self[:name] ||= 'request.faraday'
12
13
  end
13
14
 
15
+ remove_method :instrumenter
14
16
  # @return [Class]
15
17
  def instrumenter
16
18
  self[:instrumenter] ||= ActiveSupport::Notifications
@@ -52,3 +54,5 @@ module Faraday
52
54
  end
53
55
  end
54
56
  end
57
+
58
+ Faraday::Request.register_middleware(instrumentation: Faraday::Request::Instrumentation)
@@ -40,7 +40,16 @@ module Faraday
40
40
  end
41
41
 
42
42
  def body?(env)
43
- (body = env[:body]) && !(body.respond_to?(:to_str) && body.empty?)
43
+ body = env[:body]
44
+ case body
45
+ when true, false
46
+ true
47
+ when nil
48
+ # NOTE: nil can be converted to `"null"`, but this middleware doesn't process `nil` for the compatibility.
49
+ false
50
+ else
51
+ !(body.respond_to?(:to_str) && body.empty?)
52
+ end
44
53
  end
45
54
 
46
55
  def request_type(env)
@@ -31,7 +31,9 @@ module Faraday
31
31
  return unless process_request?(env)
32
32
 
33
33
  env.request_headers[CONTENT_TYPE] ||= self.class.mime_type
34
- yield(env.body) unless env.body.respond_to?(:to_str)
34
+ return if env.body.respond_to?(:to_str) || env.body.respond_to?(:read)
35
+
36
+ yield(env.body)
35
37
  end
36
38
 
37
39
  # @param env [Faraday::Env]
@@ -54,3 +56,5 @@ module Faraday
54
56
  end
55
57
  end
56
58
  end
59
+
60
+ Faraday::Request.register_middleware(url_encoded: Faraday::Request::UrlEncoded)
@@ -21,31 +21,16 @@ module Faraday
21
21
  # @!attribute headers
22
22
  # @return [Faraday::Utils::Headers] headers
23
23
  # @!attribute body
24
- # @return [Hash] body
24
+ # @return [String] body
25
25
  # @!attribute options
26
26
  # @return [RequestOptions] options
27
- #
28
- # rubocop:disable Style/StructInheritance
29
- class Request < Struct.new(
30
- :http_method, :path, :params, :headers, :body, :options
31
- )
32
- # rubocop:enable Style/StructInheritance
33
-
27
+ Request = Struct.new(:http_method, :path, :params, :headers, :body, :options) do
34
28
  extend MiddlewareRegistry
35
29
 
36
- register_middleware File.expand_path('request', __dir__),
37
- url_encoded: [:UrlEncoded, 'url_encoded'],
38
- authorization: [:Authorization, 'authorization'],
39
- basic_auth: [
40
- :BasicAuthentication,
41
- 'basic_authentication'
42
- ],
43
- token_auth: [
44
- :TokenAuthentication,
45
- 'token_authentication'
46
- ],
47
- instrumentation: [:Instrumentation, 'instrumentation'],
48
- json: [:Json, 'json']
30
+ alias_method :member_get, :[]
31
+ private :member_get
32
+ alias_method :member_set, :[]=
33
+ private :member_set
49
34
 
50
35
  # @param request_method [String]
51
36
  # @yield [request] for block customization, if block given
@@ -57,14 +42,7 @@ module Faraday
57
42
  end
58
43
  end
59
44
 
60
- def method
61
- warn <<~TEXT
62
- WARNING: `Faraday::Request##{__method__}` is deprecated; use `#http_method` instead. It will be removed in or after version 2.0.
63
- `Faraday::Request##{__method__}` called from #{caller_locations(1..1).first}
64
- TEXT
65
- http_method
66
- end
67
-
45
+ remove_method :params=
68
46
  # Replace params, preserving the existing hash type.
69
47
  #
70
48
  # @param hash [Hash] new params
@@ -72,10 +50,11 @@ module Faraday
72
50
  if params
73
51
  params.replace hash
74
52
  else
75
- super
53
+ member_set(:params, hash)
76
54
  end
77
55
  end
78
56
 
57
+ remove_method :headers=
79
58
  # Replace request headers, preserving the existing hash type.
80
59
  #
81
60
  # @param hash [Hash] new headers
@@ -83,7 +62,7 @@ module Faraday
83
62
  if headers
84
63
  headers.replace hash
85
64
  else
86
- super
65
+ member_set(:headers, hash)
87
66
  end
88
67
  end
89
68
 
@@ -153,3 +132,8 @@ module Faraday
153
132
  end
154
133
  end
155
134
  end
135
+
136
+ require 'faraday/request/authorization'
137
+ require 'faraday/request/instrumentation'
138
+ require 'faraday/request/json'
139
+ require 'faraday/request/url_encoded'
@@ -6,11 +6,11 @@ module Faraday
6
6
  class Response
7
7
  # Parse response bodies as JSON.
8
8
  class Json < Middleware
9
- def initialize(app = nil, options = {})
9
+ def initialize(app = nil, parser_options: nil, content_type: /\bjson$/, preserve_raw: false)
10
10
  super(app)
11
- @parser_options = options[:parser_options]
12
- @content_types = Array(options[:content_type] || /\bjson$/)
13
- @preserve_raw = options[:preserve_raw]
11
+ @parser_options = parser_options
12
+ @content_types = Array(content_type)
13
+ @preserve_raw = preserve_raw
14
14
  end
15
15
 
16
16
  def on_complete(env)
@@ -26,6 +26,12 @@ module Faraday
26
26
  def on_complete(env)
27
27
  @formatter.response(env)
28
28
  end
29
+
30
+ def on_error(exc)
31
+ @formatter.exception(exc) if @formatter.respond_to?(:exception)
32
+ end
29
33
  end
30
34
  end
31
35
  end
36
+
37
+ Faraday::Response.register_middleware(logger: Faraday::Response::Logger)
@@ -24,6 +24,8 @@ module Faraday
24
24
  # mimic the behavior that we get with proxy requests with HTTPS
25
25
  msg = %(407 "Proxy Authentication Required")
26
26
  raise Faraday::ProxyAuthError.new(msg, response_values(env))
27
+ when 408
28
+ raise Faraday::RequestTimeoutError, response_values(env)
27
29
  when 409
28
30
  raise Faraday::ConflictError, response_values(env)
29
31
  when 422
@@ -44,13 +46,21 @@ module Faraday
44
46
  body: env.body,
45
47
  request: {
46
48
  method: env.method,
49
+ url: env.url,
47
50
  url_path: env.url.path,
48
- params: env.params,
51
+ params: query_params(env),
49
52
  headers: env.request_headers,
50
53
  body: env.request_body
51
54
  }
52
55
  }
53
56
  end
57
+
58
+ def query_params(env)
59
+ env.request.params_encoder ||= Faraday::Utils.default_params_encoder
60
+ env.params_encoder.decode(env.url.query)
61
+ end
54
62
  end
55
63
  end
56
64
  end
65
+
66
+ Faraday::Response.register_middleware(raise_error: Faraday::Response::RaiseError)
@@ -5,26 +5,9 @@ require 'forwardable'
5
5
  module Faraday
6
6
  # Response represents an HTTP response from making an HTTP request.
7
7
  class Response
8
- # Used for simple response middleware.
9
- class Middleware < Faraday::Middleware
10
- # Override this to modify the environment after the response has finished.
11
- # Calls the `parse` method if defined
12
- # `parse` method can be defined as private, public and protected
13
- def on_complete(env)
14
- return unless respond_to?(:parse, true) && env.parse_body?
15
-
16
- env.body = parse(env.body)
17
- end
18
- end
19
-
20
8
  extend Forwardable
21
9
  extend MiddlewareRegistry
22
10
 
23
- register_middleware File.expand_path('response', __dir__),
24
- raise_error: [:RaiseError, 'raise_error'],
25
- logger: [:Logger, 'logger'],
26
- json: [:Json, 'json']
27
-
28
11
  def initialize(env = nil)
29
12
  @env = Env.from(env) if env
30
13
  @on_complete_callbacks = []
@@ -55,10 +38,10 @@ module Faraday
55
38
  end
56
39
 
57
40
  def on_complete(&block)
58
- if !finished?
59
- @on_complete_callbacks << block
60
- else
41
+ if finished?
61
42
  yield(env)
43
+ else
44
+ @on_complete_callbacks << block
62
45
  end
63
46
  self
64
47
  end
@@ -78,7 +61,8 @@ module Faraday
78
61
  def to_hash
79
62
  {
80
63
  status: env.status, body: env.body,
81
- response_headers: env.response_headers
64
+ response_headers: env.response_headers,
65
+ url: env.url
82
66
  }
83
67
  end
84
68
 
@@ -101,3 +85,7 @@ module Faraday
101
85
  end
102
86
  end
103
87
  end
88
+
89
+ require 'faraday/response/json'
90
+ require 'faraday/response/logger'
91
+ require 'faraday/response/raise_error'
@@ -111,7 +111,7 @@ module Faraday
111
111
  def parse(header_string)
112
112
  return unless header_string && !header_string.empty?
113
113
 
114
- headers = header_string.split(/\r\n/)
114
+ headers = header_string.split("\r\n")
115
115
 
116
116
  # Find the last set of response headers.
117
117
  start_index = headers.rindex { |x| x.start_with?('HTTP/') } || 0
@@ -132,7 +132,12 @@ module Faraday
132
132
 
133
133
  # Join multiple values with a comma.
134
134
  def add_parsed(key, value)
135
- self[key] ? self[key] << ', ' << value : self[key] = value
135
+ if key?(key)
136
+ self[key] = self[key].to_s
137
+ self[key] << ', ' << value
138
+ else
139
+ self[key] = value
140
+ end
136
141
  end
137
142
  end
138
143
  end
data/lib/faraday/utils.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'base64'
4
+ require 'uri'
3
5
  require 'faraday/utils/headers'
4
6
  require 'faraday/utils/params_hash'
5
7
 
@@ -51,6 +53,12 @@ module Faraday
51
53
  @default_params_encoder ||= NestedParamsEncoder
52
54
  end
53
55
 
56
+ def basic_header_from(login, pass)
57
+ value = Base64.encode64("#{login}:#{pass}")
58
+ value.delete!("\n")
59
+ "Basic #{value}"
60
+ end
61
+
54
62
  class << self
55
63
  attr_writer :default_params_encoder
56
64
  end
@@ -71,10 +79,7 @@ module Faraday
71
79
  end
72
80
 
73
81
  def default_uri_parser
74
- @default_uri_parser ||= begin
75
- require 'uri'
76
- Kernel.method(:URI)
77
- end
82
+ @default_uri_parser ||= Kernel.method(:URI)
78
83
  end
79
84
 
80
85
  def default_uri_parser=(parser)
@@ -96,7 +101,7 @@ module Faraday
96
101
  # Recursive hash update
97
102
  def deep_merge!(target, hash)
98
103
  hash.each do |key, value|
99
- target[key] = if value.is_a?(Hash) && target[key].is_a?(Hash)
104
+ target[key] = if value.is_a?(Hash) && (target[key].is_a?(Hash) || target[key].is_a?(Options))
100
105
  deep_merge(target[key], value)
101
106
  else
102
107
  value
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Faraday
4
- VERSION = '1.10.0'
4
+ VERSION = '2.7.10'
5
5
  end
data/lib/faraday.rb CHANGED
@@ -4,16 +4,10 @@ require 'cgi'
4
4
  require 'date'
5
5
  require 'set'
6
6
  require 'forwardable'
7
- require 'faraday/middleware_registry'
8
- require 'faraday/dependency_loader'
9
-
10
- unless defined?(::Faraday::Timer)
11
- require 'timeout'
12
- ::Faraday::Timer = Timeout
13
- end
14
-
15
7
  require 'faraday/version'
16
8
  require 'faraday/methods'
9
+ require 'faraday/error'
10
+ require 'faraday/middleware_registry'
17
11
  require 'faraday/utils'
18
12
  require 'faraday/options'
19
13
  require 'faraday/connection'
@@ -23,27 +17,7 @@ require 'faraday/middleware'
23
17
  require 'faraday/adapter'
24
18
  require 'faraday/request'
25
19
  require 'faraday/response'
26
- require 'faraday/error'
27
- require 'faraday/request/url_encoded' # needed by multipart
28
-
29
- # External Middleware gems and their aliases
30
- require 'faraday/multipart'
31
- require 'faraday/retry'
32
- Faraday::Request::Multipart = Faraday::Multipart::Middleware
33
- Faraday::Request::Retry = Faraday::Retry::Middleware
34
-
35
- # External Adapters gems
36
- unless defined?(JRUBY_VERSION)
37
- require 'faraday/em_http'
38
- require 'faraday/em_synchrony'
39
- end
40
- require 'faraday/excon'
41
- require 'faraday/httpclient'
42
20
  require 'faraday/net_http'
43
- require 'faraday/net_http_persistent'
44
- require 'faraday/patron'
45
- require 'faraday/rack'
46
-
47
21
  # This is the main namespace for Faraday.
48
22
  #
49
23
  # It provides methods to create {Connection} objects, and HTTP-related
@@ -80,6 +54,10 @@ module Faraday
80
54
  # @return [Symbol] the new default_adapter.
81
55
  attr_reader :default_adapter
82
56
 
57
+ # Option for the default_adapter
58
+ # @return [Hash] default_adapter options
59
+ attr_accessor :default_adapter_options
60
+
83
61
  # Documented below, see default_connection
84
62
  attr_writer :default_connection
85
63
 
@@ -116,23 +94,10 @@ module Faraday
116
94
  # params: { page: 1 }
117
95
  # # => Faraday::Connection to http://faraday.com?page=1
118
96
  def new(url = nil, options = {}, &block)
119
- options = default_connection_options.merge(options)
97
+ options = Utils.deep_merge(default_connection_options, options)
120
98
  Faraday::Connection.new(url, options, &block)
121
99
  end
122
100
 
123
- # @private
124
- # Internal: Requires internal Faraday libraries.
125
- #
126
- # @param libs [Array] one or more relative String names to Faraday classes.
127
- # @return [void]
128
- def require_libs(*libs)
129
- libs.each do |lib|
130
- require "#{lib_path}/#{lib}"
131
- end
132
- end
133
-
134
- alias require_lib require_libs
135
-
136
101
  # Documented elsewhere, see default_adapter reader
137
102
  def default_adapter=(adapter)
138
103
  @default_connection = nil
@@ -188,6 +153,5 @@ module Faraday
188
153
  self.root_path = File.expand_path __dir__
189
154
  self.lib_path = File.expand_path 'faraday', __dir__
190
155
  self.default_adapter = :net_http
191
-
192
- require_lib 'autoload' unless ENV['FARADAY_NO_AUTOLOAD']
156
+ self.default_adapter_options = {}
193
157
  end
@@ -373,5 +373,70 @@ RSpec.describe Faraday::Adapter::Test do
373
373
  it_behaves_like 'does not raise NotFound even when headers do not satisfy the strict check', '/with_user_agent', { authorization: 'Bearer m_ck', user_agent: 'My Agent' }
374
374
  it_behaves_like 'does not raise NotFound even when headers do not satisfy the strict check', '/with_user_agent', { authorization: 'Bearer m_ck', user_agent: 'My Agent', x_special: 'special' }
375
375
  end
376
+
377
+ describe 'body_match?' do
378
+ let(:stubs) do
379
+ described_class::Stubs.new do |stubs|
380
+ stubs.post('/no_check') { [200, {}, 'ok'] }
381
+ stubs.post('/with_string', 'abc') { [200, {}, 'ok'] }
382
+ stubs.post(
383
+ '/with_proc',
384
+ ->(request_body) { JSON.parse(request_body, symbolize_names: true) == { x: '!', a: [{ m: [{ a: true }], n: 123 }] } },
385
+ { content_type: 'application/json' }
386
+ ) do
387
+ [200, {}, 'ok']
388
+ end
389
+ end
390
+ end
391
+
392
+ context 'when trying without any args for body' do
393
+ subject(:without_body) { connection.post('/no_check') }
394
+
395
+ it { expect(without_body.status).to eq 200 }
396
+ end
397
+
398
+ context 'when trying with string body stubs' do
399
+ subject(:with_string) { connection.post('/with_string', 'abc') }
400
+
401
+ it { expect(with_string.status).to eq 200 }
402
+ end
403
+
404
+ context 'when trying with proc body stubs' do
405
+ subject(:with_proc) do
406
+ connection.post('/with_proc', JSON.dump(a: [{ n: 123, m: [{ a: true }] }], x: '!'), { 'Content-Type' => 'application/json' })
407
+ end
408
+
409
+ it { expect(with_proc.status).to eq 200 }
410
+ end
411
+ end
412
+ end
413
+
414
+ describe 'request timeout' do
415
+ subject(:request) do
416
+ connection.get('/sleep') do |req|
417
+ req.options.timeout = timeout
418
+ end
419
+ end
420
+
421
+ before do
422
+ stubs.get('/sleep') do
423
+ sleep(0.01)
424
+ [200, {}, '']
425
+ end
426
+ end
427
+
428
+ context 'when request is within timeout' do
429
+ let(:timeout) { 1 }
430
+
431
+ it { expect(request.status).to eq 200 }
432
+ end
433
+
434
+ context 'when request is too slow' do
435
+ let(:timeout) { 0.001 }
436
+
437
+ it 'raises an exception' do
438
+ expect { request }.to raise_error(Faraday::TimeoutError)
439
+ end
440
+ end
376
441
  end
377
442
  end