faraday 0.11.0 → 1.4.3
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 +5 -5
- data/CHANGELOG.md +380 -0
- data/LICENSE.md +1 -1
- data/README.md +25 -229
- data/Rakefile +7 -0
- data/examples/client_spec.rb +65 -0
- data/examples/client_test.rb +79 -0
- data/lib/faraday/adapter/httpclient.rb +83 -59
- data/lib/faraday/adapter/patron.rb +92 -36
- data/lib/faraday/adapter/rack.rb +30 -13
- data/lib/faraday/adapter/test.rb +103 -62
- data/lib/faraday/adapter/typhoeus.rb +7 -115
- data/lib/faraday/adapter.rb +77 -22
- data/lib/faraday/adapter_registry.rb +30 -0
- data/lib/faraday/autoload.rb +42 -36
- data/lib/faraday/connection.rb +351 -167
- data/lib/faraday/dependency_loader.rb +37 -0
- data/lib/faraday/encoders/flat_params_encoder.rb +105 -0
- data/lib/faraday/encoders/nested_params_encoder.rb +176 -0
- data/lib/faraday/error.rb +127 -38
- data/lib/faraday/file_part.rb +128 -0
- data/lib/faraday/logging/formatter.rb +105 -0
- data/lib/faraday/methods.rb +6 -0
- data/lib/faraday/middleware.rb +19 -25
- data/lib/faraday/middleware_registry.rb +129 -0
- data/lib/faraday/options/connection_options.rb +22 -0
- data/lib/faraday/options/env.rb +181 -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 +59 -0
- data/lib/faraday/options.rb +58 -207
- data/lib/faraday/param_part.rb +53 -0
- data/lib/faraday/parameters.rb +4 -196
- data/lib/faraday/rack_builder.rb +84 -48
- data/lib/faraday/request/authorization.rb +44 -30
- data/lib/faraday/request/basic_authentication.rb +14 -7
- data/lib/faraday/request/instrumentation.rb +45 -27
- data/lib/faraday/request/multipart.rb +88 -45
- data/lib/faraday/request/retry.rb +211 -126
- data/lib/faraday/request/token_authentication.rb +15 -10
- data/lib/faraday/request/url_encoded.rb +43 -23
- data/lib/faraday/request.rb +94 -32
- data/lib/faraday/response/logger.rb +22 -69
- data/lib/faraday/response/raise_error.rb +49 -14
- data/lib/faraday/response.rb +27 -23
- data/lib/faraday/utils/headers.rb +139 -0
- data/lib/faraday/utils/params_hash.rb +61 -0
- data/lib/faraday/utils.rb +38 -238
- data/lib/faraday/version.rb +5 -0
- data/lib/faraday.rb +124 -187
- data/spec/external_adapters/faraday_specs_setup.rb +14 -0
- data/spec/faraday/adapter/em_http_spec.rb +47 -0
- data/spec/faraday/adapter/em_synchrony_spec.rb +16 -0
- data/spec/faraday/adapter/excon_spec.rb +49 -0
- data/spec/faraday/adapter/httpclient_spec.rb +73 -0
- data/spec/faraday/adapter/net_http_spec.rb +64 -0
- data/spec/faraday/adapter/patron_spec.rb +18 -0
- data/spec/faraday/adapter/rack_spec.rb +8 -0
- data/spec/faraday/adapter/test_spec.rb +260 -0
- data/spec/faraday/adapter/typhoeus_spec.rb +7 -0
- data/spec/faraday/adapter_registry_spec.rb +28 -0
- data/spec/faraday/adapter_spec.rb +55 -0
- data/spec/faraday/composite_read_io_spec.rb +80 -0
- data/spec/faraday/connection_spec.rb +736 -0
- data/spec/faraday/error_spec.rb +60 -0
- data/spec/faraday/middleware_spec.rb +52 -0
- data/spec/faraday/options/env_spec.rb +70 -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 +142 -0
- data/spec/faraday/rack_builder_spec.rb +345 -0
- data/spec/faraday/request/authorization_spec.rb +88 -0
- data/spec/faraday/request/instrumentation_spec.rb +76 -0
- data/spec/faraday/request/multipart_spec.rb +302 -0
- data/spec/faraday/request/retry_spec.rb +242 -0
- data/spec/faraday/request/url_encoded_spec.rb +83 -0
- data/spec/faraday/request_spec.rb +120 -0
- data/spec/faraday/response/logger_spec.rb +220 -0
- data/spec/faraday/response/middleware_spec.rb +68 -0
- data/spec/faraday/response/raise_error_spec.rb +169 -0
- data/spec/faraday/response_spec.rb +75 -0
- data/spec/faraday/utils/headers_spec.rb +82 -0
- data/spec/faraday/utils_spec.rb +56 -0
- data/spec/faraday_spec.rb +37 -0
- data/spec/spec_helper.rb +132 -0
- data/spec/support/disabling_stub.rb +14 -0
- data/spec/support/fake_safe_buffer.rb +15 -0
- data/spec/support/helper_methods.rb +133 -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 +262 -0
- data/spec/support/streaming_response_checker.rb +35 -0
- data/spec/support/webmock_rack_app.rb +68 -0
- metadata +164 -16
- 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 -80
- data/lib/faraday/adapter/net_http.rb +0 -135
- data/lib/faraday/adapter/net_http_persistent.rb +0 -50
- data/lib/faraday/upload_io.rb +0 -67
data/lib/faraday/adapter/test.rb
CHANGED
@@ -1,51 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Faraday
|
2
4
|
class Adapter
|
3
|
-
#
|
4
|
-
#
|
5
|
+
# @example
|
5
6
|
# test = Faraday::Connection.new do
|
6
7
|
# use Faraday::Adapter::Test do |stub|
|
7
|
-
# #
|
8
|
+
# # Define matcher to match the request
|
8
9
|
# stub.get '/resource.json' do
|
9
10
|
# # return static content
|
10
11
|
# [200, {'Content-Type' => 'application/json'}, 'hi world']
|
11
12
|
# end
|
12
|
-
#
|
13
|
+
#
|
13
14
|
# # response with content generated based on request
|
14
15
|
# stub.get '/showget' do |env|
|
15
16
|
# [200, {'Content-Type' => 'text/plain'}, env[:method].to_s]
|
16
17
|
# end
|
17
|
-
#
|
18
|
-
# # regular expression can be used as matching filter
|
18
|
+
#
|
19
|
+
# # A regular expression can be used as matching filter
|
19
20
|
# stub.get /\A\/items\/(\d+)\z/ do |env, meta|
|
20
|
-
# # in case regular expression is used an instance of MatchData
|
21
|
-
#
|
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
|
+
# ]
|
22
27
|
# end
|
23
28
|
# end
|
24
29
|
# end
|
25
|
-
#
|
30
|
+
#
|
26
31
|
# resp = test.get '/resource.json'
|
27
32
|
# resp.body # => 'hi world'
|
28
|
-
#
|
33
|
+
#
|
29
34
|
# resp = test.get '/showget'
|
30
35
|
# resp.body # => 'get'
|
31
|
-
#
|
36
|
+
#
|
32
37
|
# resp = test.get '/items/1'
|
33
38
|
# resp.body # => 'showing item: 1'
|
34
|
-
#
|
39
|
+
#
|
35
40
|
# resp = test.get '/items/2'
|
36
41
|
# resp.body # => 'showing item: 2'
|
37
|
-
#
|
38
|
-
|
39
42
|
class Test < Faraday::Adapter
|
40
43
|
attr_accessor :stubs
|
41
44
|
|
45
|
+
# A stack of Stubs
|
42
46
|
class Stubs
|
43
47
|
class NotFound < StandardError
|
44
48
|
end
|
45
49
|
|
46
50
|
def initialize
|
47
|
-
# {:
|
48
|
-
@stack
|
51
|
+
# { get: [Stub, Stub] }
|
52
|
+
@stack = {}
|
53
|
+
@consumed = {}
|
49
54
|
yield(self) if block_given?
|
50
55
|
end
|
51
56
|
|
@@ -53,17 +58,18 @@ module Faraday
|
|
53
58
|
@stack.empty?
|
54
59
|
end
|
55
60
|
|
56
|
-
def match(request_method, path, headers, body)
|
57
|
-
return false
|
61
|
+
def match(request_method, host, path, headers, body)
|
62
|
+
return false unless @stack.key?(request_method)
|
63
|
+
|
58
64
|
stack = @stack[request_method]
|
59
65
|
consumed = (@consumed[request_method] ||= [])
|
60
66
|
|
61
|
-
stub, meta = matches?(stack, path, headers, body)
|
67
|
+
stub, meta = matches?(stack, host, path, headers, body)
|
62
68
|
if stub
|
63
69
|
consumed << stack.delete(stub)
|
64
70
|
return stub, meta
|
65
71
|
end
|
66
|
-
matches?(consumed, path, headers, body)
|
72
|
+
matches?(consumed, host, path, headers, body)
|
67
73
|
end
|
68
74
|
|
69
75
|
def get(path, headers = {}, &block)
|
@@ -74,15 +80,15 @@ module Faraday
|
|
74
80
|
new_stub(:head, path, headers, &block)
|
75
81
|
end
|
76
82
|
|
77
|
-
def post(path, body=nil, headers = {}, &block)
|
83
|
+
def post(path, body = nil, headers = {}, &block)
|
78
84
|
new_stub(:post, path, headers, body, &block)
|
79
85
|
end
|
80
86
|
|
81
|
-
def put(path, body=nil, headers = {}, &block)
|
87
|
+
def put(path, body = nil, headers = {}, &block)
|
82
88
|
new_stub(:put, path, headers, body, &block)
|
83
89
|
end
|
84
90
|
|
85
|
-
def patch(path, body=nil, headers = {}, &block)
|
91
|
+
def patch(path, body = nil, headers = {}, &block)
|
86
92
|
new_stub(:patch, path, headers, body, &block)
|
87
93
|
end
|
88
94
|
|
@@ -98,56 +104,79 @@ module Faraday
|
|
98
104
|
def verify_stubbed_calls
|
99
105
|
failed_stubs = []
|
100
106
|
@stack.each do |method, stubs|
|
101
|
-
|
102
|
-
|
107
|
+
next if stubs.empty?
|
108
|
+
|
109
|
+
failed_stubs.concat(
|
110
|
+
stubs.map do |stub|
|
103
111
|
"Expected #{method} #{stub}."
|
104
|
-
|
105
|
-
|
112
|
+
end
|
113
|
+
)
|
106
114
|
end
|
107
|
-
raise failed_stubs.join(
|
115
|
+
raise failed_stubs.join(' ') unless failed_stubs.empty?
|
108
116
|
end
|
109
117
|
|
110
118
|
protected
|
111
119
|
|
112
|
-
def new_stub(request_method, path, headers = {}, body=nil, &block)
|
113
|
-
normalized_path =
|
114
|
-
|
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
|
115
133
|
end
|
116
134
|
|
117
|
-
def matches?(stack, path, headers, body)
|
135
|
+
def matches?(stack, host, path, headers, body)
|
118
136
|
stack.each do |stub|
|
119
|
-
match_result, meta = stub.matches?(path, headers, body)
|
137
|
+
match_result, meta = stub.matches?(host, path, headers, body)
|
120
138
|
return stub, meta if match_result
|
121
139
|
end
|
122
140
|
nil
|
123
141
|
end
|
124
142
|
end
|
125
143
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
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)
|
133
158
|
end
|
134
159
|
|
135
|
-
def matches?(request_uri, request_headers, request_body)
|
160
|
+
def matches?(request_host, request_uri, request_headers, request_body)
|
136
161
|
request_path, request_query = request_uri.split('?')
|
137
|
-
request_params =
|
138
|
-
|
139
|
-
|
140
|
-
|
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
|
141
169
|
# that will be yielded to consumer block
|
142
170
|
meta = {}
|
143
|
-
|
171
|
+
[(host.nil? || host == request_host) &&
|
172
|
+
path_match?(request_path, meta) &&
|
144
173
|
params_match?(request_params) &&
|
145
174
|
(body.to_s.size.zero? || request_body == body) &&
|
146
|
-
headers_match?(request_headers), meta
|
175
|
+
headers_match?(request_headers), meta]
|
147
176
|
end
|
148
177
|
|
149
178
|
def path_match?(request_path, meta)
|
150
|
-
if path.is_a?
|
179
|
+
if path.is_a?(Regexp)
|
151
180
|
!!(meta[:match_data] = path.match(request_path))
|
152
181
|
else
|
153
182
|
path == request_path
|
@@ -171,7 +200,7 @@ module Faraday
|
|
171
200
|
end
|
172
201
|
end
|
173
202
|
|
174
|
-
def initialize(app, stubs=nil, &block)
|
203
|
+
def initialize(app, stubs = nil, &block)
|
175
204
|
super(app)
|
176
205
|
@stubs = stubs || Stubs.new
|
177
206
|
configure(&block) if block
|
@@ -183,21 +212,33 @@ module Faraday
|
|
183
212
|
|
184
213
|
def call(env)
|
185
214
|
super
|
215
|
+
host = env[:url].host
|
186
216
|
normalized_path = Faraday::Utils.normalize_path(env[:url])
|
187
|
-
params_encoder = env.request.params_encoder ||
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
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
|
196
238
|
stub.block.call(env, meta)
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
end
|
239
|
+
end
|
240
|
+
save_response(env, status, body, headers)
|
241
|
+
|
201
242
|
@app.call(env)
|
202
243
|
end
|
203
244
|
end
|
@@ -1,123 +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
|
-
|
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
|
-
perform_request env
|
15
|
-
@app.call env
|
16
|
-
end
|
17
|
-
|
18
|
-
def perform_request(env)
|
19
|
-
read_body env
|
20
|
-
|
21
|
-
hydra = env[:parallel_manager] || self.class.setup_parallel_manager
|
22
|
-
hydra.queue request(env)
|
23
|
-
hydra.run unless parallel?(env)
|
24
|
-
rescue Errno::ECONNREFUSED
|
25
|
-
raise Error::ConnectionFailed, $!
|
26
|
-
end
|
27
|
-
|
28
|
-
# TODO: support streaming requests
|
29
|
-
def read_body(env)
|
30
|
-
env[:body] = env[:body].read if env[:body].respond_to? :read
|
31
|
-
end
|
32
|
-
|
33
|
-
def request(env)
|
34
|
-
method = env[:method]
|
35
|
-
# For some reason, prevents Typhoeus from using "100-continue".
|
36
|
-
# We want this because Webrick 1.3.1 can't seem to handle it w/ PUT.
|
37
|
-
method = method.to_s.upcase if method == :put
|
38
|
-
|
39
|
-
req = ::Typhoeus::Request.new env[:url].to_s,
|
40
|
-
:method => method,
|
41
|
-
:body => env[:body],
|
42
|
-
:headers => env[:request_headers],
|
43
|
-
:disable_ssl_peer_verification => (env[:ssl] && env[:ssl].disable?)
|
44
|
-
|
45
|
-
configure_ssl req, env
|
46
|
-
configure_proxy req, env
|
47
|
-
configure_timeout req, env
|
48
|
-
configure_socket req, env
|
49
|
-
|
50
|
-
req.on_complete do |resp|
|
51
|
-
if resp.timed_out?
|
52
|
-
if parallel?(env)
|
53
|
-
# TODO: error callback in async mode
|
54
|
-
else
|
55
|
-
raise Faraday::Error::TimeoutError, "request timed out"
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
case resp.curl_return_code
|
60
|
-
when 0
|
61
|
-
# everything OK
|
62
|
-
when 7
|
63
|
-
raise Error::ConnectionFailed, resp.curl_error_message
|
64
|
-
when 60
|
65
|
-
raise Faraday::SSLError, resp.curl_error_message
|
66
|
-
else
|
67
|
-
raise Error::ClientError, resp.curl_error_message
|
68
|
-
end
|
69
|
-
|
70
|
-
save_response(env, resp.code, resp.body) do |response_headers|
|
71
|
-
response_headers.parse resp.headers
|
72
|
-
end
|
73
|
-
# in async mode, :response is initialized at this point
|
74
|
-
env[:response].finish(env) if parallel?(env)
|
75
|
-
end
|
76
|
-
|
77
|
-
req
|
78
|
-
end
|
79
|
-
|
80
|
-
def configure_ssl(req, env)
|
81
|
-
ssl = env[:ssl]
|
82
|
-
|
83
|
-
req.ssl_version = ssl[:version] if ssl[:version]
|
84
|
-
req.ssl_cert = ssl[:client_cert] if ssl[:client_cert]
|
85
|
-
req.ssl_key = ssl[:client_key] if ssl[:client_key]
|
86
|
-
req.ssl_cacert = ssl[:ca_file] if ssl[:ca_file]
|
87
|
-
req.ssl_capath = ssl[:ca_path] if ssl[:ca_path]
|
88
|
-
end
|
89
|
-
|
90
|
-
def configure_proxy(req, env)
|
91
|
-
proxy = request_options(env)[:proxy]
|
92
|
-
return unless proxy
|
93
|
-
|
94
|
-
req.proxy = "#{proxy[:uri].host}:#{proxy[:uri].port}"
|
95
|
-
|
96
|
-
if proxy[:user] && proxy[:password]
|
97
|
-
req.proxy_username = proxy[:user]
|
98
|
-
req.proxy_password = proxy[:password]
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
def configure_timeout(req, env)
|
103
|
-
env_req = request_options(env)
|
104
|
-
req.timeout = req.connect_timeout = (env_req[:timeout] * 1000) if env_req[:timeout]
|
105
|
-
req.connect_timeout = (env_req[:open_timeout] * 1000) if env_req[:open_timeout]
|
106
|
-
end
|
107
|
-
|
108
|
-
def configure_socket(req, env)
|
109
|
-
if bind = request_options(env)[:bind]
|
110
|
-
req.interface = bind[:host]
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def request_options(env)
|
115
|
-
env[:request]
|
116
|
-
end
|
117
|
-
|
118
|
-
def parallel?(env)
|
119
|
-
!!env[:parallel_manager]
|
120
|
-
end
|
12
|
+
dependency 'typhoeus/adapters/faraday'
|
121
13
|
end
|
122
14
|
end
|
123
15
|
end
|
data/lib/faraday/adapter.rb
CHANGED
@@ -1,53 +1,108 @@
|
|
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
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
# Public: This module marks an Adapter as supporting parallel requests.
|
6
|
+
class Adapter
|
7
|
+
extend MiddlewareRegistry
|
8
|
+
extend DependencyLoader
|
9
|
+
|
10
|
+
CONTENT_LENGTH = 'Content-Length'
|
11
|
+
|
12
|
+
register_middleware File.expand_path('adapter', __dir__),
|
13
|
+
test: [:Test, 'test'],
|
14
|
+
typhoeus: [:Typhoeus, 'typhoeus'],
|
15
|
+
patron: [:Patron, 'patron'],
|
16
|
+
rack: [:Rack, 'rack'],
|
17
|
+
httpclient: [:HTTPClient, 'httpclient']
|
18
|
+
|
19
|
+
# This module marks an Adapter as supporting parallel requests.
|
20
20
|
module Parallelism
|
21
21
|
attr_writer :supports_parallel
|
22
|
-
|
22
|
+
|
23
|
+
def supports_parallel?
|
24
|
+
@supports_parallel
|
25
|
+
end
|
23
26
|
|
24
27
|
def inherited(subclass)
|
25
28
|
super
|
26
|
-
subclass.supports_parallel =
|
29
|
+
subclass.supports_parallel = supports_parallel?
|
27
30
|
end
|
28
31
|
end
|
29
32
|
|
30
33
|
extend Parallelism
|
31
34
|
self.supports_parallel = false
|
32
35
|
|
33
|
-
def initialize(
|
34
|
-
|
36
|
+
def initialize(_app = nil, opts = {}, &block)
|
37
|
+
@app = ->(env) { env.response }
|
35
38
|
@connection_options = opts
|
36
39
|
@config_block = block
|
37
40
|
end
|
38
41
|
|
42
|
+
# Yields or returns an adapter's configured connection. Depends on
|
43
|
+
# #build_connection being defined on this adapter.
|
44
|
+
#
|
45
|
+
# @param env [Faraday::Env, Hash] The env object for a faraday request.
|
46
|
+
#
|
47
|
+
# @return The return value of the given block, or the HTTP connection object
|
48
|
+
# if no block is given.
|
49
|
+
def connection(env)
|
50
|
+
conn = build_connection(env)
|
51
|
+
return conn unless block_given?
|
52
|
+
|
53
|
+
yield conn
|
54
|
+
end
|
55
|
+
|
56
|
+
# Close any persistent connections. The adapter should still be usable
|
57
|
+
# after calling close.
|
58
|
+
def close
|
59
|
+
# Possible implementation:
|
60
|
+
# @app.close if @app.respond_to?(:close)
|
61
|
+
end
|
62
|
+
|
39
63
|
def call(env)
|
40
64
|
env.clear_body if env.needs_body?
|
65
|
+
env.response = Response.new
|
41
66
|
end
|
42
67
|
|
68
|
+
private
|
69
|
+
|
43
70
|
def save_response(env, status, body, headers = nil, reason_phrase = nil)
|
44
71
|
env.status = status
|
45
72
|
env.body = body
|
46
|
-
env.reason_phrase = reason_phrase
|
73
|
+
env.reason_phrase = reason_phrase&.to_s&.strip
|
47
74
|
env.response_headers = Utils::Headers.new.tap do |response_headers|
|
48
75
|
response_headers.update headers unless headers.nil?
|
49
76
|
yield(response_headers) if block_given?
|
50
77
|
end
|
78
|
+
|
79
|
+
env.response.finish(env) unless env.parallel?
|
80
|
+
env.response
|
81
|
+
end
|
82
|
+
|
83
|
+
# Fetches either a read, write, or open timeout setting. Defaults to the
|
84
|
+
# :timeout value if a more specific one is not given.
|
85
|
+
#
|
86
|
+
# @param type [Symbol] Describes which timeout setting to get: :read,
|
87
|
+
# :write, or :open.
|
88
|
+
# @param options [Hash] Hash containing Symbol keys like :timeout,
|
89
|
+
# :read_timeout, :write_timeout, :open_timeout, or
|
90
|
+
# :timeout
|
91
|
+
#
|
92
|
+
# @return [Integer, nil] Timeout duration in seconds, or nil if no timeout
|
93
|
+
# has been set.
|
94
|
+
def request_timeout(type, options)
|
95
|
+
key = TIMEOUT_KEYS.fetch(type) do
|
96
|
+
msg = "Expected :read, :write, :open. Got #{type.inspect} :("
|
97
|
+
raise ArgumentError, msg
|
98
|
+
end
|
99
|
+
options[key] || options[:timeout]
|
51
100
|
end
|
101
|
+
|
102
|
+
TIMEOUT_KEYS = {
|
103
|
+
read: :read_timeout,
|
104
|
+
open: :open_timeout,
|
105
|
+
write: :write_timeout
|
106
|
+
}.freeze
|
52
107
|
end
|
53
108
|
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
|