faraday 0.7.4 → 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.
Files changed (119) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +276 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +40 -153
  5. data/Rakefile +4 -139
  6. data/examples/client_spec.rb +65 -0
  7. data/examples/client_test.rb +79 -0
  8. data/lib/faraday/adapter/em_http.rb +286 -0
  9. data/lib/faraday/adapter/em_http_ssl_patch.rb +62 -0
  10. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +69 -0
  11. data/lib/faraday/adapter/em_synchrony.rb +120 -36
  12. data/lib/faraday/adapter/excon.rb +108 -12
  13. data/lib/faraday/adapter/httpclient.rb +152 -0
  14. data/lib/faraday/adapter/net_http.rb +187 -43
  15. data/lib/faraday/adapter/net_http_persistent.rb +91 -0
  16. data/lib/faraday/adapter/patron.rb +106 -10
  17. data/lib/faraday/adapter/rack.rb +75 -0
  18. data/lib/faraday/adapter/test.rb +160 -61
  19. data/lib/faraday/adapter/typhoeus.rb +7 -46
  20. data/lib/faraday/adapter.rb +105 -33
  21. data/lib/faraday/adapter_registry.rb +30 -0
  22. data/lib/faraday/autoload.rb +95 -0
  23. data/lib/faraday/connection.rb +525 -157
  24. data/lib/faraday/dependency_loader.rb +37 -0
  25. data/lib/faraday/encoders/flat_params_encoder.rb +98 -0
  26. data/lib/faraday/encoders/nested_params_encoder.rb +171 -0
  27. data/lib/faraday/error.rb +122 -30
  28. data/lib/faraday/file_part.rb +128 -0
  29. data/lib/faraday/logging/formatter.rb +105 -0
  30. data/lib/faraday/middleware.rb +14 -22
  31. data/lib/faraday/middleware_registry.rb +129 -0
  32. data/lib/faraday/options/connection_options.rb +22 -0
  33. data/lib/faraday/options/env.rb +181 -0
  34. data/lib/faraday/options/proxy_options.rb +28 -0
  35. data/lib/faraday/options/request_options.rb +22 -0
  36. data/lib/faraday/options/ssl_options.rb +59 -0
  37. data/lib/faraday/options.rb +222 -0
  38. data/lib/faraday/param_part.rb +53 -0
  39. data/lib/faraday/parameters.rb +5 -0
  40. data/lib/faraday/rack_builder.rb +248 -0
  41. data/lib/faraday/request/authorization.rb +55 -0
  42. data/lib/faraday/request/basic_authentication.rb +20 -0
  43. data/lib/faraday/request/instrumentation.rb +54 -0
  44. data/lib/faraday/request/multipart.rb +84 -48
  45. data/lib/faraday/request/retry.rb +239 -0
  46. data/lib/faraday/request/token_authentication.rb +20 -0
  47. data/lib/faraday/request/url_encoded.rb +46 -27
  48. data/lib/faraday/request.rb +112 -50
  49. data/lib/faraday/response/logger.rb +24 -25
  50. data/lib/faraday/response/raise_error.rb +40 -11
  51. data/lib/faraday/response.rb +44 -35
  52. data/lib/faraday/utils/headers.rb +139 -0
  53. data/lib/faraday/utils/params_hash.rb +61 -0
  54. data/lib/faraday/utils.rb +72 -117
  55. data/lib/faraday.rb +142 -64
  56. data/spec/external_adapters/faraday_specs_setup.rb +14 -0
  57. data/spec/faraday/adapter/em_http_spec.rb +47 -0
  58. data/spec/faraday/adapter/em_synchrony_spec.rb +16 -0
  59. data/spec/faraday/adapter/excon_spec.rb +49 -0
  60. data/spec/faraday/adapter/httpclient_spec.rb +73 -0
  61. data/spec/faraday/adapter/net_http_persistent_spec.rb +57 -0
  62. data/spec/faraday/adapter/net_http_spec.rb +64 -0
  63. data/spec/faraday/adapter/patron_spec.rb +18 -0
  64. data/spec/faraday/adapter/rack_spec.rb +8 -0
  65. data/spec/faraday/adapter/typhoeus_spec.rb +7 -0
  66. data/spec/faraday/adapter_registry_spec.rb +28 -0
  67. data/spec/faraday/adapter_spec.rb +55 -0
  68. data/spec/faraday/composite_read_io_spec.rb +80 -0
  69. data/spec/faraday/connection_spec.rb +691 -0
  70. data/spec/faraday/error_spec.rb +45 -0
  71. data/spec/faraday/middleware_spec.rb +26 -0
  72. data/spec/faraday/options/env_spec.rb +70 -0
  73. data/spec/faraday/options/options_spec.rb +297 -0
  74. data/spec/faraday/options/proxy_options_spec.rb +37 -0
  75. data/spec/faraday/options/request_options_spec.rb +19 -0
  76. data/spec/faraday/params_encoders/flat_spec.rb +34 -0
  77. data/spec/faraday/params_encoders/nested_spec.rb +134 -0
  78. data/spec/faraday/rack_builder_spec.rb +196 -0
  79. data/spec/faraday/request/authorization_spec.rb +88 -0
  80. data/spec/faraday/request/instrumentation_spec.rb +76 -0
  81. data/spec/faraday/request/multipart_spec.rb +274 -0
  82. data/spec/faraday/request/retry_spec.rb +242 -0
  83. data/spec/faraday/request/url_encoded_spec.rb +83 -0
  84. data/spec/faraday/request_spec.rb +109 -0
  85. data/spec/faraday/response/logger_spec.rb +220 -0
  86. data/spec/faraday/response/middleware_spec.rb +68 -0
  87. data/spec/faraday/response/raise_error_spec.rb +106 -0
  88. data/spec/faraday/response_spec.rb +75 -0
  89. data/spec/faraday/utils/headers_spec.rb +82 -0
  90. data/spec/faraday/utils_spec.rb +56 -0
  91. data/spec/faraday_spec.rb +37 -0
  92. data/spec/spec_helper.rb +132 -0
  93. data/spec/support/disabling_stub.rb +14 -0
  94. data/spec/support/fake_safe_buffer.rb +15 -0
  95. data/spec/support/helper_methods.rb +133 -0
  96. data/spec/support/shared_examples/adapter.rb +104 -0
  97. data/spec/support/shared_examples/params_encoder.rb +18 -0
  98. data/spec/support/shared_examples/request_method.rb +234 -0
  99. data/spec/support/streaming_response_checker.rb +35 -0
  100. data/spec/support/webmock_rack_app.rb +68 -0
  101. metadata +126 -126
  102. data/Gemfile +0 -29
  103. data/config.ru +0 -6
  104. data/faraday.gemspec +0 -92
  105. data/lib/faraday/adapter/action_dispatch.rb +0 -29
  106. data/lib/faraday/builder.rb +0 -160
  107. data/lib/faraday/request/json.rb +0 -35
  108. data/lib/faraday/upload_io.rb +0 -23
  109. data/test/adapters/live_test.rb +0 -205
  110. data/test/adapters/logger_test.rb +0 -37
  111. data/test/adapters/net_http_test.rb +0 -33
  112. data/test/adapters/test_middleware_test.rb +0 -70
  113. data/test/connection_test.rb +0 -254
  114. data/test/env_test.rb +0 -158
  115. data/test/helper.rb +0 -41
  116. data/test/live_server.rb +0 -45
  117. data/test/middleware_stack_test.rb +0 -118
  118. data/test/request_middleware_test.rb +0 -116
  119. data/test/response_middleware_test.rb +0 -74
@@ -1,109 +1,186 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
3
- # test = Faraday::Connection.new do
4
- # use Faraday::Adapter::Test do |stub|
5
- # stub.get '/nigiri/sake.json' do
6
- # [200, {}, 'hi world']
5
+ # @example
6
+ # test = Faraday::Connection.new do
7
+ # use Faraday::Adapter::Test do |stub|
8
+ # # Define matcher to match the request
9
+ # stub.get '/resource.json' do
10
+ # # return static content
11
+ # [200, {'Content-Type' => 'application/json'}, 'hi world']
12
+ # end
13
+ #
14
+ # # response with content generated based on request
15
+ # stub.get '/showget' do |env|
16
+ # [200, {'Content-Type' => 'text/plain'}, env[:method].to_s]
17
+ # end
18
+ #
19
+ # # A regular expression can be used as matching filter
20
+ # stub.get /\A\/items\/(\d+)\z/ do |env, meta|
21
+ # # in case regular expression is used, an instance of MatchData
22
+ # # can be received
23
+ # [200,
24
+ # {'Content-Type' => 'text/plain'},
25
+ # "showing item: #{meta[:match_data][1]}"
26
+ # ]
27
+ # end
7
28
  # end
8
29
  # end
9
- # end
10
30
  #
11
- # resp = test.get '/nigiri/sake.json'
12
- # resp.body # => 'hi world'
31
+ # resp = test.get '/resource.json'
32
+ # resp.body # => 'hi world'
33
+ #
34
+ # resp = test.get '/showget'
35
+ # resp.body # => 'get'
13
36
  #
37
+ # resp = test.get '/items/1'
38
+ # resp.body # => 'showing item: 1'
39
+ #
40
+ # resp = test.get '/items/2'
41
+ # resp.body # => 'showing item: 2'
14
42
  class Test < Faraday::Adapter
15
43
  attr_accessor :stubs
16
44
 
17
- def self.loaded?() false end
18
-
45
+ # A stack of Stubs
19
46
  class Stubs
20
47
  class NotFound < StandardError
21
48
  end
22
49
 
23
50
  def initialize
24
- # {:get => [Stub, Stub]}
25
- @stack, @consumed = {}, {}
26
- yield self if block_given?
51
+ # { get: [Stub, Stub] }
52
+ @stack = {}
53
+ @consumed = {}
54
+ yield(self) if block_given?
27
55
  end
28
56
 
29
57
  def empty?
30
58
  @stack.empty?
31
59
  end
32
60
 
33
- def match(request_method, path, body)
34
- return false if !@stack.key?(request_method)
61
+ def match(request_method, host, path, headers, body)
62
+ return false unless @stack.key?(request_method)
63
+
35
64
  stack = @stack[request_method]
36
65
  consumed = (@consumed[request_method] ||= [])
37
66
 
38
- if stub = matches?(stack, path, body)
67
+ stub, meta = matches?(stack, host, path, headers, body)
68
+ if stub
39
69
  consumed << stack.delete(stub)
40
- stub
41
- else
42
- matches?(consumed, path, body)
70
+ return stub, meta
43
71
  end
72
+ matches?(consumed, host, path, headers, body)
44
73
  end
45
74
 
46
- def get(path, &block)
47
- new_stub(:get, path, &block)
75
+ def get(path, headers = {}, &block)
76
+ new_stub(:get, path, headers, &block)
48
77
  end
49
78
 
50
- def head(path, &block)
51
- new_stub(:head, path, &block)
79
+ def head(path, headers = {}, &block)
80
+ new_stub(:head, path, headers, &block)
52
81
  end
53
82
 
54
- def post(path, body=nil, &block)
55
- new_stub(:post, path, body, &block)
83
+ def post(path, body = nil, headers = {}, &block)
84
+ new_stub(:post, path, headers, body, &block)
56
85
  end
57
86
 
58
- def put(path, body=nil, &block)
59
- new_stub(:put, path, body, &block)
87
+ def put(path, body = nil, headers = {}, &block)
88
+ new_stub(:put, path, headers, body, &block)
60
89
  end
61
90
 
62
- def delete(path, &block)
63
- new_stub(:delete, path, &block)
91
+ def patch(path, body = nil, headers = {}, &block)
92
+ new_stub(:patch, path, headers, body, &block)
93
+ end
94
+
95
+ def delete(path, headers = {}, &block)
96
+ new_stub(:delete, path, headers, &block)
97
+ end
98
+
99
+ def options(path, headers = {}, &block)
100
+ new_stub(:options, path, headers, &block)
64
101
  end
65
102
 
66
103
  # Raises an error if any of the stubbed calls have not been made.
67
104
  def verify_stubbed_calls
68
105
  failed_stubs = []
69
106
  @stack.each do |method, stubs|
70
- unless stubs.size == 0
71
- failed_stubs.concat(stubs.map {|stub|
107
+ next if stubs.empty?
108
+
109
+ failed_stubs.concat(
110
+ stubs.map do |stub|
72
111
  "Expected #{method} #{stub}."
73
- })
74
- end
112
+ end
113
+ )
75
114
  end
76
- raise failed_stubs.join(" ") unless failed_stubs.size == 0
115
+ raise failed_stubs.join(' ') unless failed_stubs.empty?
77
116
  end
78
117
 
79
118
  protected
80
119
 
81
- def new_stub(request_method, path, body=nil, &block)
82
- (@stack[request_method] ||= []) << Stub.new(path, body, block)
120
+ def new_stub(request_method, path, headers = {}, body = nil, &block)
121
+ normalized_path, host =
122
+ if path.is_a?(Regexp)
123
+ path
124
+ else
125
+ [
126
+ Faraday::Utils.normalize_path(path),
127
+ Faraday::Utils.URI(path).host
128
+ ]
129
+ end
130
+
131
+ stub = Stub.new(host, normalized_path, headers, body, block)
132
+ (@stack[request_method] ||= []) << stub
83
133
  end
84
134
 
85
- def matches?(stack, path, body)
86
- stack.detect { |stub| stub.matches?(path, body) }
135
+ def matches?(stack, host, path, headers, body)
136
+ stack.each do |stub|
137
+ match_result, meta = stub.matches?(host, path, headers, body)
138
+ return stub, meta if match_result
139
+ end
140
+ nil
87
141
  end
88
142
  end
89
143
 
90
- class Stub < Struct.new(:path, :params, :body, :block)
91
- def initialize(full, body, block)
92
- path, query = full.split('?')
93
- params = query ?
94
- Rack::Utils.parse_nested_query(query) :
95
- {}
96
- super path, params, body, block
144
+ # Stub request
145
+ # rubocop:disable Style/StructInheritance
146
+ class Stub < Struct.new(:host, :path, :params, :headers, :body, :block)
147
+ # rubocop:enable Style/StructInheritance
148
+ def initialize(host, full, headers, body, block)
149
+ path, query = full.respond_to?(:split) ? full.split('?') : full
150
+ params =
151
+ if query
152
+ Faraday::Utils.parse_nested_query(query)
153
+ else
154
+ {}
155
+ end
156
+
157
+ super(host, path, params, headers, body, block)
97
158
  end
98
159
 
99
- def matches?(request_uri, request_body)
160
+ def matches?(request_host, request_uri, request_headers, request_body)
100
161
  request_path, request_query = request_uri.split('?')
101
- request_params = request_query ?
102
- Rack::Utils.parse_nested_query(request_query) :
103
- {}
104
- request_path == path &&
162
+ request_params =
163
+ if request_query
164
+ Faraday::Utils.parse_nested_query(request_query)
165
+ else
166
+ {}
167
+ end
168
+ # meta is a hash used as carrier
169
+ # that will be yielded to consumer block
170
+ meta = {}
171
+ [(host.nil? || host == request_host) &&
172
+ path_match?(request_path, meta) &&
105
173
  params_match?(request_params) &&
106
- (body.to_s.size.zero? || request_body == body)
174
+ (body.to_s.size.zero? || request_body == body) &&
175
+ headers_match?(request_headers), meta]
176
+ end
177
+
178
+ def path_match?(request_path, meta)
179
+ if path.is_a?(Regexp)
180
+ !!(meta[:match_data] = path.match(request_path))
181
+ else
182
+ path == request_path
183
+ end
107
184
  end
108
185
 
109
186
  def params_match?(request_params)
@@ -112,34 +189,56 @@ module Faraday
112
189
  end
113
190
  end
114
191
 
192
+ def headers_match?(request_headers)
193
+ headers.keys.all? do |key|
194
+ request_headers[key] == headers[key]
195
+ end
196
+ end
197
+
115
198
  def to_s
116
199
  "#{path} #{body}"
117
200
  end
118
201
  end
119
202
 
120
- def initialize(app, stubs=nil, &block)
203
+ def initialize(app, stubs = nil, &block)
121
204
  super(app)
122
205
  @stubs = stubs || Stubs.new
123
206
  configure(&block) if block
124
207
  end
125
208
 
126
209
  def configure
127
- yield stubs
210
+ yield(stubs)
128
211
  end
129
212
 
130
213
  def call(env)
131
214
  super
215
+ host = env[:url].host
132
216
  normalized_path = Faraday::Utils.normalize_path(env[:url])
217
+ params_encoder = env.request.params_encoder ||
218
+ Faraday::Utils.default_params_encoder
219
+
220
+ stub, meta = stubs.match(env[:method], host, normalized_path,
221
+ env.request_headers, env[:body])
222
+
223
+ unless stub
224
+ raise Stubs::NotFound, "no stubbed request for #{env[:method]} "\
225
+ "#{normalized_path} #{env[:body]}"
226
+ end
227
+
228
+ env[:params] = if (query = env[:url].query)
229
+ params_encoder.decode(query)
230
+ else
231
+ {}
232
+ end
233
+ block_arity = stub.block.arity
234
+ status, headers, body =
235
+ if block_arity >= 0
236
+ stub.block.call(*[env, meta].take(block_arity))
237
+ else
238
+ stub.block.call(env, meta)
239
+ end
240
+ save_response(env, status, body, headers)
133
241
 
134
- if stub = stubs.match(env[:method], normalized_path, env[:body])
135
- env[:params] = (query = env[:url].query) ?
136
- Rack::Utils.parse_nested_query(query) :
137
- {}
138
- status, headers, body = stub.block.call(env)
139
- save_response(env, status, body, headers)
140
- else
141
- raise Stubs::NotFound, "no stubbed request for #{env[:method]} #{normalized_path} #{env[:body]}"
142
- end
143
242
  @app.call(env)
144
243
  end
145
244
  end
@@ -1,54 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
5
+ # Typhoeus adapter. This class is just a stub, the real adapter is in
6
+ # https://github.com/typhoeus/typhoeus/blob/master/lib/typhoeus/adapters/faraday.rb
3
7
  class Typhoeus < Faraday::Adapter
4
- self.supports_parallel_requests = true
5
-
6
- def self.setup_parallel_manager(options = {})
7
- options.empty? ? ::Typhoeus::Hydra.hydra : ::Typhoeus::Hydra.new(options)
8
- end
8
+ # Needs to define this method in order to support Typhoeus <= 1.3.0
9
+ def call; end
9
10
 
10
11
  dependency 'typhoeus'
11
-
12
- def call(env)
13
- super
14
-
15
- # TODO: support streaming requests
16
- env[:body] = env[:body].read if env[:body].respond_to? :read
17
-
18
- req = ::Typhoeus::Request.new env[:url].to_s,
19
- :method => env[:method],
20
- :body => env[:body],
21
- :headers => env[:request_headers],
22
- :disable_ssl_peer_verification => (env[:ssl] && !env[:ssl].fetch(:verify, true))
23
-
24
- if ssl = env[:ssl]
25
- req.ssl_cert = ssl[:client_cert_file] if ssl[:client_cert_file]
26
- req.ssl_key = ssl[:client_key_file] if ssl[:client_key_file]
27
- req.ssl_cacert = ssl[:ca_file] if ssl[:ca_file]
28
- req.ssl_capath = ssl[:ca_path] if ssl[:ca_path]
29
- end
30
-
31
- env_req = env[:request]
32
- req.timeout = req.connect_timeout = (env_req[:timeout] * 1000) if env_req[:timeout]
33
- req.connect_timeout = (env_req[:open_timeout] * 1000) if env_req[:open_timeout]
34
-
35
- is_parallel = !!env[:parallel_manager]
36
- req.on_complete do |resp|
37
- save_response(env, resp.code, resp.body) do |response_headers|
38
- response_headers.parse resp.headers
39
- end
40
- # in async mode, :response is initialized at this point
41
- env[:response].finish(env) if is_parallel
42
- end
43
-
44
- hydra = env[:parallel_manager] || self.class.setup_parallel_manager
45
- hydra.queue req
46
- hydra.run unless is_parallel
47
-
48
- @app.call env
49
- rescue Errno::ECONNREFUSED
50
- raise Error::ConnectionFailed, $!
51
- end
12
+ dependency 'typhoeus/adapters/faraday'
52
13
  end
53
14
  end
54
15
  end
@@ -1,43 +1,115 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
- class Adapter < Middleware
3
- CONTENT_LENGTH = 'Content-Length'.freeze
4
-
5
- extend AutoloadHelper
6
-
7
- autoload_all 'faraday/adapter',
8
- :ActionDispatch => 'action_dispatch',
9
- :NetHttp => 'net_http',
10
- :Typhoeus => 'typhoeus',
11
- :EMSynchrony => 'em_synchrony',
12
- :Patron => 'patron',
13
- :Excon => 'excon',
14
- :Test => 'test'
15
-
16
- register_lookup_modules \
17
- :action_dispatch => :ActionDispatch,
18
- :test => :Test,
19
- :net_http => :NetHttp,
20
- :typhoeus => :Typhoeus,
21
- :patron => :Patron,
22
- :em_synchrony => :EMSynchrony,
23
- :excon => :Excon
4
+ # Base class for all Faraday adapters. Adapters are
5
+ # responsible for fulfilling a Faraday request.
6
+ class Adapter
7
+ extend MiddlewareRegistry
8
+ extend DependencyLoader
24
9
 
25
- def call(env)
26
- if !env[:body] and Connection::METHODS_WITH_BODIES.include? env[:method]
27
- # play nice and indicate we're sending an empty body
28
- env[:request_headers][CONTENT_LENGTH] = "0"
29
- # Typhoeus hangs on PUT requests if body is nil
30
- env[:body] = ''
10
+ CONTENT_LENGTH = 'Content-Length'
11
+
12
+ register_middleware File.expand_path('adapter', __dir__),
13
+ test: [:Test, 'test'],
14
+ net_http: [:NetHttp, 'net_http'],
15
+ net_http_persistent: [
16
+ :NetHttpPersistent,
17
+ 'net_http_persistent'
18
+ ],
19
+ typhoeus: [:Typhoeus, 'typhoeus'],
20
+ patron: [:Patron, 'patron'],
21
+ em_synchrony: [:EMSynchrony, 'em_synchrony'],
22
+ em_http: [:EMHttp, 'em_http'],
23
+ excon: [:Excon, 'excon'],
24
+ rack: [:Rack, 'rack'],
25
+ httpclient: [:HTTPClient, 'httpclient']
26
+
27
+ # This module marks an Adapter as supporting parallel requests.
28
+ module Parallelism
29
+ attr_writer :supports_parallel
30
+ def supports_parallel?
31
+ @supports_parallel
32
+ end
33
+
34
+ def inherited(subclass)
35
+ super
36
+ subclass.supports_parallel = supports_parallel?
31
37
  end
32
38
  end
33
39
 
34
- def save_response(env, status, body, headers = nil)
35
- env[:status] = status
36
- env[:body] = body
37
- env[:response_headers] = Utils::Headers.new.tap do |response_headers|
40
+ extend Parallelism
41
+ self.supports_parallel = false
42
+
43
+ def initialize(_app = nil, opts = {}, &block)
44
+ @app = ->(env) { env.response }
45
+ @connection_options = opts
46
+ @config_block = block
47
+ end
48
+
49
+ # Yields or returns an adapter's configured connection. Depends on
50
+ # #build_connection being defined on this adapter.
51
+ #
52
+ # @param env [Faraday::Env, Hash] The env object for a faraday request.
53
+ #
54
+ # @return The return value of the given block, or the HTTP connection object
55
+ # if no block is given.
56
+ def connection(env)
57
+ conn = build_connection(env)
58
+ return conn unless block_given?
59
+
60
+ yield conn
61
+ end
62
+
63
+ # Close any persistent connections. The adapter should still be usable
64
+ # after calling close.
65
+ def close
66
+ # Possible implementation:
67
+ # @app.close if @app.respond_to?(:close)
68
+ end
69
+
70
+ def call(env)
71
+ env.clear_body if env.needs_body?
72
+ env.response = Response.new
73
+ end
74
+
75
+ private
76
+
77
+ def save_response(env, status, body, headers = nil, reason_phrase = nil)
78
+ env.status = status
79
+ env.body = body
80
+ env.reason_phrase = reason_phrase&.to_s&.strip
81
+ env.response_headers = Utils::Headers.new.tap do |response_headers|
38
82
  response_headers.update headers unless headers.nil?
39
- yield response_headers if block_given?
83
+ yield(response_headers) if block_given?
40
84
  end
85
+
86
+ env.response.finish(env) unless env.parallel?
87
+ env.response
41
88
  end
89
+
90
+ # Fetches either a read, write, or open timeout setting. Defaults to the
91
+ # :timeout value if a more specific one is not given.
92
+ #
93
+ # @param type [Symbol] Describes which timeout setting to get: :read,
94
+ # :write, or :open.
95
+ # @param options [Hash] Hash containing Symbol keys like :timeout,
96
+ # :read_timeout, :write_timeout, :open_timeout, or
97
+ # :timeout
98
+ #
99
+ # @return [Integer, nil] Timeout duration in seconds, or nil if no timeout
100
+ # has been set.
101
+ def request_timeout(type, options)
102
+ key = TIMEOUT_KEYS.fetch(type) do
103
+ msg = "Expected :read, :write, :open. Got #{type.inspect} :("
104
+ raise ArgumentError, msg
105
+ end
106
+ options[key] || options[:timeout]
107
+ end
108
+
109
+ TIMEOUT_KEYS = {
110
+ read: :read_timeout,
111
+ open: :open_timeout,
112
+ write: :write_timeout
113
+ }.freeze
42
114
  end
43
115
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'monitor'
4
+
5
+ module Faraday
6
+ # AdapterRegistry registers adapter class names so they can be looked up by a
7
+ # String or Symbol name.
8
+ class AdapterRegistry
9
+ def initialize
10
+ @lock = Monitor.new
11
+ @constants = {}
12
+ end
13
+
14
+ def get(name)
15
+ klass = @lock.synchronize do
16
+ @constants[name]
17
+ end
18
+ return klass if klass
19
+
20
+ Object.const_get(name).tap { |c| set(c, name) }
21
+ end
22
+
23
+ def set(klass, name = nil)
24
+ name ||= klass.to_s
25
+ @lock.synchronize do
26
+ @constants[name] = klass
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faraday
4
+ # Adds the ability for other modules to manage autoloadable
5
+ # constants.
6
+ #
7
+ # @api private
8
+ module AutoloadHelper
9
+ # Registers the constants to be auto loaded.
10
+ #
11
+ # @param prefix [String] The require prefix. If the path is inside Faraday,
12
+ # then it will be prefixed with the root path of this loaded
13
+ # Faraday version.
14
+ # @param options [{ Symbol => String }] library names.
15
+ #
16
+ # @example
17
+ #
18
+ # Faraday.autoload_all 'faraday/foo',
19
+ # Bar: 'bar'
20
+ #
21
+ # # requires faraday/foo/bar to load Faraday::Bar.
22
+ # Faraday::Bar
23
+ #
24
+ # @return [void]
25
+ def autoload_all(prefix, options)
26
+ if prefix =~ %r{^faraday(/|$)}i
27
+ prefix = File.join(Faraday.root_path, prefix)
28
+ end
29
+
30
+ options.each do |const_name, path|
31
+ autoload const_name, File.join(prefix, path)
32
+ end
33
+ end
34
+
35
+ # Loads each autoloaded constant. If thread safety is a concern,
36
+ # wrap this in a Mutex.
37
+ #
38
+ # @return [void]
39
+ def load_autoloaded_constants
40
+ constants.each do |const|
41
+ const_get(const) if autoload?(const)
42
+ end
43
+ end
44
+
45
+ # Filters the module's contents with those that have been already
46
+ # autoloaded.
47
+ #
48
+ # @return [Array<Class, Module>]
49
+ def all_loaded_constants
50
+ constants
51
+ .map { |c| const_get(c) }
52
+ .select { |a| a.respond_to?(:loaded?) && a.loaded? }
53
+ end
54
+ end
55
+
56
+ # Adapter is the base class for all Faraday adapters.
57
+ # @see lib/faraday/adapter.rb Original class location
58
+ class Adapter
59
+ extend AutoloadHelper
60
+ autoload_all 'faraday/adapter',
61
+ NetHttp: 'net_http',
62
+ NetHttpPersistent: 'net_http_persistent',
63
+ EMSynchrony: 'em_synchrony',
64
+ EMHttp: 'em_http',
65
+ Typhoeus: 'typhoeus',
66
+ Patron: 'patron',
67
+ Excon: 'excon',
68
+ Test: 'test',
69
+ Rack: 'rack',
70
+ HTTPClient: 'httpclient'
71
+ end
72
+
73
+ # Request represents a single HTTP request for a Faraday adapter to make.
74
+ # @see lib/faraday/request.rb Original class location
75
+ class Request
76
+ extend AutoloadHelper
77
+ autoload_all 'faraday/request',
78
+ UrlEncoded: 'url_encoded',
79
+ Multipart: 'multipart',
80
+ Retry: 'retry',
81
+ Authorization: 'authorization',
82
+ BasicAuthentication: 'basic_authentication',
83
+ TokenAuthentication: 'token_authentication',
84
+ Instrumentation: 'instrumentation'
85
+ end
86
+
87
+ # Response represents the returned value of a sent Faraday request.
88
+ # @see lib/faraday/response.rb Original class location
89
+ class Response
90
+ extend AutoloadHelper
91
+ autoload_all 'faraday/response',
92
+ RaiseError: 'raise_error',
93
+ Logger: 'logger'
94
+ end
95
+ end