faraday 0.17.3 → 2.7.4
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +350 -8
- data/LICENSE.md +1 -1
- data/README.md +27 -367
- data/Rakefile +1 -7
- data/examples/client_spec.rb +119 -0
- data/examples/client_test.rb +144 -0
- data/lib/faraday/adapter/test.rb +170 -72
- data/lib/faraday/adapter.rb +69 -23
- data/lib/faraday/adapter_registry.rb +30 -0
- data/lib/faraday/connection.rb +309 -233
- data/lib/faraday/encoders/flat_params_encoder.rb +105 -0
- data/lib/faraday/encoders/nested_params_encoder.rb +183 -0
- data/lib/faraday/error.rb +31 -42
- data/lib/faraday/logging/formatter.rb +122 -0
- data/lib/faraday/methods.rb +6 -0
- data/lib/faraday/middleware.rb +21 -25
- data/lib/faraday/middleware_registry.rb +83 -0
- data/lib/faraday/options/connection_options.rb +22 -0
- data/lib/faraday/options/env.rb +205 -0
- data/lib/faraday/options/proxy_options.rb +32 -0
- data/lib/faraday/options/request_options.rb +22 -0
- data/lib/faraday/options/ssl_options.rb +69 -0
- data/lib/faraday/options.rb +38 -193
- data/lib/faraday/parameters.rb +4 -197
- data/lib/faraday/rack_builder.rb +91 -76
- data/lib/faraday/request/authorization.rb +42 -29
- data/lib/faraday/request/instrumentation.rb +47 -27
- data/lib/faraday/request/json.rb +55 -0
- data/lib/faraday/request/url_encoded.rb +48 -24
- data/lib/faraday/request.rb +64 -42
- data/lib/faraday/response/json.rb +54 -0
- data/lib/faraday/response/logger.rb +24 -67
- data/lib/faraday/response/raise_error.rb +57 -18
- data/lib/faraday/response.rb +26 -32
- data/lib/faraday/utils/headers.rb +144 -0
- data/lib/faraday/utils/params_hash.rb +61 -0
- data/lib/faraday/utils.rb +47 -251
- data/lib/faraday/version.rb +5 -0
- data/lib/faraday.rb +108 -198
- data/spec/external_adapters/faraday_specs_setup.rb +14 -0
- data/spec/faraday/adapter/test_spec.rb +442 -0
- data/spec/faraday/adapter_registry_spec.rb +28 -0
- data/spec/faraday/adapter_spec.rb +55 -0
- data/spec/faraday/connection_spec.rb +808 -0
- data/spec/faraday/error_spec.rb +12 -54
- data/spec/faraday/middleware_registry_spec.rb +31 -0
- data/spec/faraday/middleware_spec.rb +70 -0
- data/spec/faraday/options/env_spec.rb +76 -0
- data/spec/faraday/options/options_spec.rb +297 -0
- data/spec/faraday/options/proxy_options_spec.rb +44 -0
- data/spec/faraday/options/request_options_spec.rb +19 -0
- data/spec/faraday/params_encoders/flat_spec.rb +42 -0
- data/spec/faraday/params_encoders/nested_spec.rb +150 -0
- data/spec/faraday/rack_builder_spec.rb +317 -0
- data/spec/faraday/request/authorization_spec.rb +118 -0
- data/spec/faraday/request/instrumentation_spec.rb +74 -0
- data/spec/faraday/request/json_spec.rb +111 -0
- data/spec/faraday/request/url_encoded_spec.rb +93 -0
- data/spec/faraday/request_spec.rb +110 -0
- data/spec/faraday/response/json_spec.rb +117 -0
- data/spec/faraday/response/logger_spec.rb +248 -0
- data/spec/faraday/response/raise_error_spec.rb +81 -15
- data/spec/faraday/response_spec.rb +77 -0
- data/spec/faraday/utils/headers_spec.rb +100 -0
- data/spec/faraday/utils_spec.rb +118 -0
- data/spec/faraday_spec.rb +37 -0
- data/spec/spec_helper.rb +63 -36
- data/spec/support/disabling_stub.rb +14 -0
- data/spec/support/fake_safe_buffer.rb +15 -0
- data/spec/support/helper_methods.rb +96 -0
- data/spec/support/shared_examples/adapter.rb +105 -0
- data/spec/support/shared_examples/params_encoder.rb +18 -0
- data/spec/support/shared_examples/request_method.rb +263 -0
- data/spec/support/streaming_response_checker.rb +35 -0
- metadata +76 -59
- data/lib/faraday/adapter/em_http.rb +0 -243
- data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -56
- data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -66
- data/lib/faraday/adapter/em_synchrony.rb +0 -106
- data/lib/faraday/adapter/excon.rb +0 -82
- data/lib/faraday/adapter/httpclient.rb +0 -128
- data/lib/faraday/adapter/net_http.rb +0 -152
- data/lib/faraday/adapter/net_http_persistent.rb +0 -68
- data/lib/faraday/adapter/patron.rb +0 -95
- data/lib/faraday/adapter/rack.rb +0 -58
- data/lib/faraday/adapter/typhoeus.rb +0 -12
- data/lib/faraday/autoload.rb +0 -84
- data/lib/faraday/deprecate.rb +0 -107
- data/lib/faraday/request/basic_authentication.rb +0 -13
- data/lib/faraday/request/multipart.rb +0 -68
- data/lib/faraday/request/retry.rb +0 -213
- data/lib/faraday/request/token_authentication.rb +0 -15
- data/lib/faraday/upload_io.rb +0 -67
- data/spec/faraday/deprecate_spec.rb +0 -69
- data/test/adapters/default_test.rb +0 -14
- data/test/adapters/em_http_test.rb +0 -30
- data/test/adapters/em_synchrony_test.rb +0 -32
- data/test/adapters/excon_test.rb +0 -30
- data/test/adapters/httpclient_test.rb +0 -34
- data/test/adapters/integration.rb +0 -263
- data/test/adapters/logger_test.rb +0 -136
- data/test/adapters/net_http_persistent_test.rb +0 -114
- data/test/adapters/net_http_test.rb +0 -79
- data/test/adapters/patron_test.rb +0 -40
- data/test/adapters/rack_test.rb +0 -38
- data/test/adapters/test_middleware_test.rb +0 -157
- data/test/adapters/typhoeus_test.rb +0 -38
- data/test/authentication_middleware_test.rb +0 -65
- data/test/composite_read_io_test.rb +0 -109
- data/test/connection_test.rb +0 -738
- data/test/env_test.rb +0 -268
- data/test/helper.rb +0 -75
- data/test/live_server.rb +0 -67
- data/test/middleware/instrumentation_test.rb +0 -88
- data/test/middleware/retry_test.rb +0 -282
- data/test/middleware_stack_test.rb +0 -260
- data/test/multibyte.txt +0 -1
- data/test/options_test.rb +0 -333
- data/test/parameters_test.rb +0 -157
- data/test/request_middleware_test.rb +0 -126
- data/test/response_middleware_test.rb +0 -72
- data/test/strawberry.rb +0 -2
- data/test/utils_test.rb +0 -98
data/lib/faraday/adapter/test.rb
CHANGED
@@ -1,51 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'timeout'
|
4
|
+
|
1
5
|
module Faraday
|
2
6
|
class Adapter
|
3
|
-
#
|
4
|
-
#
|
7
|
+
# @example
|
5
8
|
# test = Faraday::Connection.new do
|
6
9
|
# use Faraday::Adapter::Test do |stub|
|
7
|
-
# #
|
10
|
+
# # Define matcher to match the request
|
8
11
|
# stub.get '/resource.json' do
|
9
12
|
# # return static content
|
10
13
|
# [200, {'Content-Type' => 'application/json'}, 'hi world']
|
11
14
|
# end
|
12
|
-
#
|
15
|
+
#
|
13
16
|
# # response with content generated based on request
|
14
17
|
# stub.get '/showget' do |env|
|
15
18
|
# [200, {'Content-Type' => 'text/plain'}, env[:method].to_s]
|
16
19
|
# end
|
17
|
-
#
|
18
|
-
# # regular expression can be used as matching filter
|
20
|
+
#
|
21
|
+
# # A regular expression can be used as matching filter
|
19
22
|
# stub.get /\A\/items\/(\d+)\z/ do |env, meta|
|
20
|
-
# # in case regular expression is used an instance of MatchData
|
21
|
-
#
|
23
|
+
# # in case regular expression is used, an instance of MatchData
|
24
|
+
# # can be received
|
25
|
+
# [200,
|
26
|
+
# {'Content-Type' => 'text/plain'},
|
27
|
+
# "showing item: #{meta[:match_data][1]}"
|
28
|
+
# ]
|
22
29
|
# end
|
30
|
+
#
|
31
|
+
# # Test the request body is the same as the stubbed body
|
32
|
+
# stub.post('/bar', 'name=YK&word=call') { [200, {}, ''] }
|
33
|
+
#
|
34
|
+
# # You can pass a proc as a stubbed body and check the request body in your way.
|
35
|
+
# # In this case, the proc should return true or false.
|
36
|
+
# stub.post('/foo', ->(request_body) do
|
37
|
+
# JSON.parse(request_body).slice('name') == { 'name' => 'YK' } }) { [200, {}, '']
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# # You can set strict_mode to exactly match the stubbed requests.
|
41
|
+
# stub.strict_mode = true
|
23
42
|
# end
|
24
43
|
# end
|
25
|
-
#
|
44
|
+
#
|
26
45
|
# resp = test.get '/resource.json'
|
27
46
|
# resp.body # => 'hi world'
|
28
|
-
#
|
47
|
+
#
|
29
48
|
# resp = test.get '/showget'
|
30
49
|
# resp.body # => 'get'
|
31
|
-
#
|
50
|
+
#
|
32
51
|
# resp = test.get '/items/1'
|
33
52
|
# resp.body # => 'showing item: 1'
|
34
|
-
#
|
53
|
+
#
|
35
54
|
# resp = test.get '/items/2'
|
36
55
|
# resp.body # => 'showing item: 2'
|
37
56
|
#
|
38
|
-
|
57
|
+
# resp = test.post '/bar', 'name=YK&word=call'
|
58
|
+
# resp.status # => 200
|
59
|
+
#
|
60
|
+
# resp = test.post '/foo', JSON.dump(name: 'YK', created_at: Time.now)
|
61
|
+
# resp.status # => 200
|
39
62
|
class Test < Faraday::Adapter
|
40
63
|
attr_accessor :stubs
|
41
64
|
|
65
|
+
# A stack of Stubs
|
42
66
|
class Stubs
|
43
67
|
class NotFound < StandardError
|
44
68
|
end
|
45
69
|
|
46
|
-
def initialize
|
47
|
-
# {:
|
48
|
-
@stack
|
70
|
+
def initialize(strict_mode: false)
|
71
|
+
# { get: [Stub, Stub] }
|
72
|
+
@stack = {}
|
73
|
+
@consumed = {}
|
74
|
+
@strict_mode = strict_mode
|
75
|
+
@stubs_mutex = Monitor.new
|
49
76
|
yield(self) if block_given?
|
50
77
|
end
|
51
78
|
|
@@ -53,17 +80,23 @@ module Faraday
|
|
53
80
|
@stack.empty?
|
54
81
|
end
|
55
82
|
|
56
|
-
|
57
|
-
|
83
|
+
# @param env [Faraday::Env]
|
84
|
+
def match(env)
|
85
|
+
request_method = env[:method]
|
86
|
+
return false unless @stack.key?(request_method)
|
87
|
+
|
58
88
|
stack = @stack[request_method]
|
59
89
|
consumed = (@consumed[request_method] ||= [])
|
60
90
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
91
|
+
@stubs_mutex.synchronize do
|
92
|
+
stub, meta = matches?(stack, env)
|
93
|
+
if stub
|
94
|
+
removed = stack.delete(stub)
|
95
|
+
consumed << removed unless removed.nil?
|
96
|
+
return stub, meta
|
97
|
+
end
|
65
98
|
end
|
66
|
-
matches?(consumed,
|
99
|
+
matches?(consumed, env)
|
67
100
|
end
|
68
101
|
|
69
102
|
def get(path, headers = {}, &block)
|
@@ -74,15 +107,15 @@ module Faraday
|
|
74
107
|
new_stub(:head, path, headers, &block)
|
75
108
|
end
|
76
109
|
|
77
|
-
def post(path, body=nil, headers = {}, &block)
|
110
|
+
def post(path, body = nil, headers = {}, &block)
|
78
111
|
new_stub(:post, path, headers, body, &block)
|
79
112
|
end
|
80
113
|
|
81
|
-
def put(path, body=nil, headers = {}, &block)
|
114
|
+
def put(path, body = nil, headers = {}, &block)
|
82
115
|
new_stub(:put, path, headers, body, &block)
|
83
116
|
end
|
84
117
|
|
85
|
-
def patch(path, body=nil, headers = {}, &block)
|
118
|
+
def patch(path, body = nil, headers = {}, &block)
|
86
119
|
new_stub(:patch, path, headers, body, &block)
|
87
120
|
end
|
88
121
|
|
@@ -98,87 +131,131 @@ module Faraday
|
|
98
131
|
def verify_stubbed_calls
|
99
132
|
failed_stubs = []
|
100
133
|
@stack.each do |method, stubs|
|
101
|
-
|
102
|
-
|
134
|
+
next if stubs.empty?
|
135
|
+
|
136
|
+
failed_stubs.concat(
|
137
|
+
stubs.map do |stub|
|
103
138
|
"Expected #{method} #{stub}."
|
104
|
-
|
139
|
+
end
|
140
|
+
)
|
141
|
+
end
|
142
|
+
raise failed_stubs.join(' ') unless failed_stubs.empty?
|
143
|
+
end
|
144
|
+
|
145
|
+
# Set strict_mode. If the value is true, this adapter tries to find matched requests strictly,
|
146
|
+
# which means that all of a path, parameters, and headers must be the same as an actual request.
|
147
|
+
def strict_mode=(value)
|
148
|
+
@strict_mode = value
|
149
|
+
@stack.each do |_method, stubs|
|
150
|
+
stubs.each do |stub|
|
151
|
+
stub.strict_mode = value
|
105
152
|
end
|
106
153
|
end
|
107
|
-
raise failed_stubs.join(" ") unless failed_stubs.size == 0
|
108
154
|
end
|
109
155
|
|
110
156
|
protected
|
111
157
|
|
112
|
-
def new_stub(request_method, path, headers = {}, body=nil, &block)
|
158
|
+
def new_stub(request_method, path, headers = {}, body = nil, &block)
|
113
159
|
normalized_path, host =
|
114
160
|
if path.is_a?(Regexp)
|
115
161
|
path
|
116
162
|
else
|
117
|
-
[
|
163
|
+
[
|
164
|
+
Faraday::Utils.normalize_path(path),
|
165
|
+
Faraday::Utils.URI(path).host
|
166
|
+
]
|
118
167
|
end
|
168
|
+
path, query = normalized_path.respond_to?(:split) ? normalized_path.split('?') : normalized_path
|
169
|
+
headers = Utils::Headers.new(headers)
|
119
170
|
|
120
|
-
|
171
|
+
stub = Stub.new(host, path, query, headers, body, @strict_mode, block)
|
172
|
+
(@stack[request_method] ||= []) << stub
|
121
173
|
end
|
122
174
|
|
123
|
-
|
175
|
+
# @param stack [Hash]
|
176
|
+
# @param env [Faraday::Env]
|
177
|
+
def matches?(stack, env)
|
124
178
|
stack.each do |stub|
|
125
|
-
match_result, meta = stub.matches?(
|
179
|
+
match_result, meta = stub.matches?(env)
|
126
180
|
return stub, meta if match_result
|
127
181
|
end
|
128
182
|
nil
|
129
183
|
end
|
130
184
|
end
|
131
185
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
request_path, request_query = request_uri.split('?')
|
143
|
-
request_params = request_query ?
|
144
|
-
Faraday::Utils.parse_nested_query(request_query) :
|
145
|
-
{}
|
146
|
-
# meta is a hash use as carrier
|
186
|
+
# Stub request
|
187
|
+
class Stub < Struct.new(:host, :path, :query, :headers, :body, :strict_mode, :block) # rubocop:disable Style/StructInheritance
|
188
|
+
# @param env [Faraday::Env]
|
189
|
+
def matches?(env)
|
190
|
+
request_host = env[:url].host
|
191
|
+
request_path = Faraday::Utils.normalize_path(env[:url].path)
|
192
|
+
request_headers = env.request_headers
|
193
|
+
request_body = env[:body]
|
194
|
+
|
195
|
+
# meta is a hash used as carrier
|
147
196
|
# that will be yielded to consumer block
|
148
197
|
meta = {}
|
149
|
-
|
198
|
+
[(host.nil? || host == request_host) &&
|
150
199
|
path_match?(request_path, meta) &&
|
151
|
-
params_match?(
|
152
|
-
(
|
153
|
-
headers_match?(request_headers), meta
|
200
|
+
params_match?(env) &&
|
201
|
+
body_match?(request_body) &&
|
202
|
+
headers_match?(request_headers), meta]
|
154
203
|
end
|
155
204
|
|
156
205
|
def path_match?(request_path, meta)
|
157
|
-
if path.is_a?
|
206
|
+
if path.is_a?(Regexp)
|
158
207
|
!!(meta[:match_data] = path.match(request_path))
|
159
208
|
else
|
160
209
|
path == request_path
|
161
210
|
end
|
162
211
|
end
|
163
212
|
|
164
|
-
|
213
|
+
# @param env [Faraday::Env]
|
214
|
+
def params_match?(env)
|
215
|
+
request_params = env[:params]
|
216
|
+
params = env.params_encoder.decode(query) || {}
|
217
|
+
|
218
|
+
if strict_mode
|
219
|
+
return Set.new(params) == Set.new(request_params)
|
220
|
+
end
|
221
|
+
|
165
222
|
params.keys.all? do |key|
|
166
223
|
request_params[key] == params[key]
|
167
224
|
end
|
168
225
|
end
|
169
226
|
|
170
227
|
def headers_match?(request_headers)
|
228
|
+
if strict_mode
|
229
|
+
headers_with_user_agent = headers.dup.tap do |hs|
|
230
|
+
# NOTE: Set User-Agent in case it's not set when creating Stubs.
|
231
|
+
# Users would not want to set Faraday's User-Agent explicitly.
|
232
|
+
hs[:user_agent] ||= Connection::USER_AGENT
|
233
|
+
end
|
234
|
+
return Set.new(headers_with_user_agent) == Set.new(request_headers)
|
235
|
+
end
|
236
|
+
|
171
237
|
headers.keys.all? do |key|
|
172
238
|
request_headers[key] == headers[key]
|
173
239
|
end
|
174
240
|
end
|
175
241
|
|
242
|
+
def body_match?(request_body)
|
243
|
+
return true if body.to_s.empty?
|
244
|
+
|
245
|
+
case body
|
246
|
+
when Proc
|
247
|
+
body.call(request_body)
|
248
|
+
else
|
249
|
+
request_body == body
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
176
253
|
def to_s
|
177
254
|
"#{path} #{body}"
|
178
255
|
end
|
179
256
|
end
|
180
257
|
|
181
|
-
def initialize(app, stubs=nil, &block)
|
258
|
+
def initialize(app, stubs = nil, &block)
|
182
259
|
super(app)
|
183
260
|
@stubs = stubs || Stubs.new
|
184
261
|
configure(&block) if block
|
@@ -188,26 +265,47 @@ module Faraday
|
|
188
265
|
yield(stubs)
|
189
266
|
end
|
190
267
|
|
268
|
+
# @param env [Faraday::Env]
|
191
269
|
def call(env)
|
192
270
|
super
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
block_arity = stub.block.arity
|
202
|
-
status, headers, body = (block_arity >= 0) ?
|
203
|
-
stub.block.call(*[env, meta].take(block_arity)) :
|
204
|
-
stub.block.call(env, meta)
|
205
|
-
save_response(env, status, body, headers)
|
206
|
-
else
|
207
|
-
raise Stubs::NotFound, "no stubbed request for #{env[:method]} #{normalized_path} #{env[:body]}"
|
271
|
+
|
272
|
+
env.request.params_encoder ||= Faraday::Utils.default_params_encoder
|
273
|
+
env[:params] = env.params_encoder.decode(env[:url].query) || {}
|
274
|
+
stub, meta = stubs.match(env)
|
275
|
+
|
276
|
+
unless stub
|
277
|
+
raise Stubs::NotFound, "no stubbed request for #{env[:method]} " \
|
278
|
+
"#{env[:url]} #{env[:body]}"
|
208
279
|
end
|
280
|
+
|
281
|
+
block_arity = stub.block.arity
|
282
|
+
params = if block_arity >= 0
|
283
|
+
[env, meta].take(block_arity)
|
284
|
+
else
|
285
|
+
[env, meta]
|
286
|
+
end
|
287
|
+
|
288
|
+
timeout = request_timeout(:open, env[:request])
|
289
|
+
timeout ||= request_timeout(:read, env[:request])
|
290
|
+
|
291
|
+
status, headers, body =
|
292
|
+
if timeout
|
293
|
+
::Timeout.timeout(timeout, Faraday::TimeoutError) do
|
294
|
+
stub.block.call(*params)
|
295
|
+
end
|
296
|
+
else
|
297
|
+
stub.block.call(*params)
|
298
|
+
end
|
299
|
+
|
300
|
+
# We need to explicitly pass `reason_phrase = nil` here to avoid keyword args conflicts.
|
301
|
+
# See https://github.com/lostisland/faraday/issues/1444
|
302
|
+
# TODO: remove `nil` explicit reason_phrase once Ruby 3.0 becomes minimum req. version
|
303
|
+
save_response(env, status, body, headers, nil)
|
304
|
+
|
209
305
|
@app.call(env)
|
210
306
|
end
|
211
307
|
end
|
212
308
|
end
|
213
309
|
end
|
310
|
+
|
311
|
+
Faraday::Adapter.register_middleware(test: Faraday::Adapter::Test)
|
data/lib/faraday/adapter.rb
CHANGED
@@ -1,55 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Faraday
|
2
|
-
#
|
4
|
+
# Base class for all Faraday adapters. Adapters are
|
3
5
|
# responsible for fulfilling a Faraday request.
|
4
|
-
class Adapter
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
:net_http_persistent => [:NetHttpPersistent, 'net_http_persistent'],
|
11
|
-
:typhoeus => [:Typhoeus, 'typhoeus'],
|
12
|
-
:patron => [:Patron, 'patron'],
|
13
|
-
:em_synchrony => [:EMSynchrony, 'em_synchrony'],
|
14
|
-
:em_http => [:EMHttp, 'em_http'],
|
15
|
-
:excon => [:Excon, 'excon'],
|
16
|
-
:rack => [:Rack, 'rack'],
|
17
|
-
:httpclient => [:HTTPClient, 'httpclient']
|
18
|
-
|
19
|
-
# Public: This module marks an Adapter as supporting parallel requests.
|
6
|
+
class Adapter
|
7
|
+
extend MiddlewareRegistry
|
8
|
+
|
9
|
+
CONTENT_LENGTH = 'Content-Length'
|
10
|
+
|
11
|
+
# This module marks an Adapter as supporting parallel requests.
|
20
12
|
module Parallelism
|
21
13
|
attr_writer :supports_parallel
|
22
|
-
|
14
|
+
|
15
|
+
def supports_parallel?
|
16
|
+
@supports_parallel
|
17
|
+
end
|
23
18
|
|
24
19
|
def inherited(subclass)
|
25
20
|
super
|
26
|
-
subclass.supports_parallel =
|
21
|
+
subclass.supports_parallel = supports_parallel?
|
27
22
|
end
|
28
23
|
end
|
29
24
|
|
30
25
|
extend Parallelism
|
31
26
|
self.supports_parallel = false
|
32
27
|
|
33
|
-
def initialize(
|
34
|
-
|
28
|
+
def initialize(_app = nil, opts = {}, &block)
|
29
|
+
@app = ->(env) { env.response }
|
35
30
|
@connection_options = opts
|
36
31
|
@config_block = block
|
37
32
|
end
|
38
33
|
|
34
|
+
# Yields or returns an adapter's configured connection. Depends on
|
35
|
+
# #build_connection being defined on this adapter.
|
36
|
+
#
|
37
|
+
# @param env [Faraday::Env, Hash] The env object for a faraday request.
|
38
|
+
#
|
39
|
+
# @return The return value of the given block, or the HTTP connection object
|
40
|
+
# if no block is given.
|
41
|
+
def connection(env)
|
42
|
+
conn = build_connection(env)
|
43
|
+
return conn unless block_given?
|
44
|
+
|
45
|
+
yield conn
|
46
|
+
end
|
47
|
+
|
48
|
+
# Close any persistent connections. The adapter should still be usable
|
49
|
+
# after calling close.
|
50
|
+
def close
|
51
|
+
# Possible implementation:
|
52
|
+
# @app.close if @app.respond_to?(:close)
|
53
|
+
end
|
54
|
+
|
39
55
|
def call(env)
|
40
56
|
env.clear_body if env.needs_body?
|
57
|
+
env.response = Response.new
|
41
58
|
end
|
42
59
|
|
43
60
|
private
|
44
61
|
|
45
|
-
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)
|
46
63
|
env.status = status
|
47
64
|
env.body = body
|
48
|
-
env.reason_phrase = reason_phrase
|
65
|
+
env.reason_phrase = reason_phrase&.to_s&.strip
|
49
66
|
env.response_headers = Utils::Headers.new.tap do |response_headers|
|
50
67
|
response_headers.update headers unless headers.nil?
|
51
68
|
yield(response_headers) if block_given?
|
52
69
|
end
|
70
|
+
|
71
|
+
env.response.finish(env) unless env.parallel? || !finished
|
72
|
+
env.response
|
73
|
+
end
|
74
|
+
|
75
|
+
# Fetches either a read, write, or open timeout setting. Defaults to the
|
76
|
+
# :timeout value if a more specific one is not given.
|
77
|
+
#
|
78
|
+
# @param type [Symbol] Describes which timeout setting to get: :read,
|
79
|
+
# :write, or :open.
|
80
|
+
# @param options [Hash] Hash containing Symbol keys like :timeout,
|
81
|
+
# :read_timeout, :write_timeout, or :open_timeout
|
82
|
+
#
|
83
|
+
# @return [Integer, nil] Timeout duration in seconds, or nil if no timeout
|
84
|
+
# has been set.
|
85
|
+
def request_timeout(type, options)
|
86
|
+
key = TIMEOUT_KEYS.fetch(type) do
|
87
|
+
msg = "Expected :read, :write, :open. Got #{type.inspect} :("
|
88
|
+
raise ArgumentError, msg
|
89
|
+
end
|
90
|
+
options[key] || options[:timeout]
|
53
91
|
end
|
92
|
+
|
93
|
+
TIMEOUT_KEYS = {
|
94
|
+
read: :read_timeout,
|
95
|
+
open: :open_timeout,
|
96
|
+
write: :write_timeout
|
97
|
+
}.freeze
|
54
98
|
end
|
55
99
|
end
|
100
|
+
|
101
|
+
require 'faraday/adapter/test'
|
@@ -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
|