faraday 0.16.2 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.md +1 -1
- data/README.md +347 -18
- data/lib/faraday.rb +175 -93
- data/lib/faraday/adapter.rb +22 -36
- data/lib/faraday/adapter/em_http.rb +99 -142
- data/lib/faraday/adapter/em_http_ssl_patch.rb +17 -23
- data/lib/faraday/adapter/em_synchrony.rb +60 -104
- data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +15 -18
- data/lib/faraday/adapter/excon.rb +55 -100
- data/lib/faraday/adapter/httpclient.rb +39 -61
- data/lib/faraday/adapter/net_http.rb +51 -104
- data/lib/faraday/adapter/net_http_persistent.rb +27 -48
- data/lib/faraday/adapter/patron.rb +35 -54
- data/lib/faraday/adapter/rack.rb +12 -28
- data/lib/faraday/adapter/test.rb +53 -86
- data/lib/faraday/adapter/typhoeus.rb +1 -4
- data/lib/faraday/autoload.rb +36 -47
- data/lib/faraday/connection.rb +179 -321
- data/lib/faraday/error.rb +32 -80
- data/lib/faraday/middleware.rb +28 -4
- data/lib/faraday/options.rb +186 -35
- data/lib/faraday/parameters.rb +197 -4
- data/lib/faraday/rack_builder.rb +56 -67
- data/lib/faraday/request.rb +36 -68
- data/lib/faraday/request/authorization.rb +30 -42
- data/lib/faraday/request/basic_authentication.rb +7 -14
- data/lib/faraday/request/instrumentation.rb +27 -45
- data/lib/faraday/request/multipart.rb +48 -79
- data/lib/faraday/request/retry.rb +170 -197
- data/lib/faraday/request/token_authentication.rb +10 -15
- data/lib/faraday/request/url_encoded.rb +23 -41
- data/lib/faraday/response.rb +16 -23
- data/lib/faraday/response/logger.rb +69 -22
- data/lib/faraday/response/raise_error.rb +14 -36
- data/lib/faraday/upload_io.rb +67 -0
- data/lib/faraday/utils.rb +245 -28
- metadata +5 -22
- data/lib/faraday/adapter_registry.rb +0 -28
- data/lib/faraday/dependency_loader.rb +0 -37
- data/lib/faraday/deprecated_class.rb +0 -28
- data/lib/faraday/encoders/flat_params_encoder.rb +0 -94
- data/lib/faraday/encoders/nested_params_encoder.rb +0 -171
- data/lib/faraday/file_part.rb +0 -128
- data/lib/faraday/logging/formatter.rb +0 -92
- data/lib/faraday/middleware_registry.rb +0 -129
- data/lib/faraday/options/connection_options.rb +0 -22
- data/lib/faraday/options/env.rb +0 -181
- data/lib/faraday/options/proxy_options.rb +0 -28
- data/lib/faraday/options/request_options.rb +0 -21
- data/lib/faraday/options/ssl_options.rb +0 -59
- data/lib/faraday/param_part.rb +0 -53
- data/lib/faraday/utils/headers.rb +0 -139
- data/lib/faraday/utils/params_hash.rb +0 -61
- data/spec/external_adapters/faraday_specs_setup.rb +0 -14
data/lib/faraday/error.rb
CHANGED
@@ -1,25 +1,21 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'faraday/deprecated_class'
|
4
|
-
|
5
|
-
# Faraday namespace.
|
6
1
|
module Faraday
|
7
|
-
|
8
|
-
|
2
|
+
class Error < StandardError; end
|
3
|
+
|
4
|
+
class ClientError < Error
|
9
5
|
attr_reader :response, :wrapped_exception
|
10
6
|
|
11
|
-
def initialize(
|
7
|
+
def initialize(ex, response = nil)
|
12
8
|
@wrapped_exception = nil
|
13
9
|
@response = response
|
14
10
|
|
15
|
-
if
|
16
|
-
super(
|
17
|
-
@wrapped_exception =
|
18
|
-
elsif
|
19
|
-
super("the server responded with status #{
|
20
|
-
@response =
|
11
|
+
if ex.respond_to?(:backtrace)
|
12
|
+
super(ex.message)
|
13
|
+
@wrapped_exception = ex
|
14
|
+
elsif ex.respond_to?(:each_key)
|
15
|
+
super("the server responded with status #{ex[:status]}")
|
16
|
+
@response = ex
|
21
17
|
else
|
22
|
-
super(
|
18
|
+
super(ex.to_s)
|
23
19
|
end
|
24
20
|
end
|
25
21
|
|
@@ -32,83 +28,39 @@ module Faraday
|
|
32
28
|
end
|
33
29
|
|
34
30
|
def inspect
|
35
|
-
inner =
|
36
|
-
|
37
|
-
|
38
|
-
|
31
|
+
inner = ''
|
32
|
+
if @wrapped_exception
|
33
|
+
inner << " wrapped=#{@wrapped_exception.inspect}"
|
34
|
+
end
|
35
|
+
if @response
|
36
|
+
inner << " response=#{@response.inspect}"
|
37
|
+
end
|
38
|
+
if inner.empty?
|
39
|
+
inner << " #{super}"
|
40
|
+
end
|
39
41
|
%(#<#{self.class}#{inner}>)
|
40
42
|
end
|
41
43
|
end
|
42
44
|
|
43
|
-
|
44
|
-
class
|
45
|
-
end
|
46
|
-
|
47
|
-
# Raised by Faraday::Response::RaiseError in case of a 400 response.
|
48
|
-
class BadRequestError < ClientError
|
49
|
-
end
|
45
|
+
class ConnectionFailed < ClientError; end
|
46
|
+
class ResourceNotFound < ClientError; end
|
47
|
+
class ParsingError < ClientError; end
|
50
48
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
# Raised by Faraday::Response::RaiseError in case of a 403 response.
|
56
|
-
class ForbiddenError < ClientError
|
57
|
-
end
|
58
|
-
|
59
|
-
# Raised by Faraday::Response::RaiseError in case of a 404 response.
|
60
|
-
class ResourceNotFound < ClientError
|
61
|
-
end
|
62
|
-
|
63
|
-
# Raised by Faraday::Response::RaiseError in case of a 407 response.
|
64
|
-
class ProxyAuthError < ClientError
|
65
|
-
end
|
66
|
-
|
67
|
-
# Raised by Faraday::Response::RaiseError in case of a 409 response.
|
68
|
-
class ConflictError < ClientError
|
69
|
-
end
|
70
|
-
|
71
|
-
# Raised by Faraday::Response::RaiseError in case of a 422 response.
|
72
|
-
class UnprocessableEntityError < ClientError
|
73
|
-
end
|
74
|
-
|
75
|
-
# Faraday server error class. Represents 5xx status responses.
|
76
|
-
class ServerError < Error
|
77
|
-
end
|
78
|
-
|
79
|
-
# A unified client error for timeouts.
|
80
|
-
class TimeoutError < ServerError
|
81
|
-
def initialize(exc = 'timeout', response = nil)
|
82
|
-
super(exc, response)
|
49
|
+
class TimeoutError < ClientError
|
50
|
+
def initialize(ex = nil)
|
51
|
+
super(ex || "timeout")
|
83
52
|
end
|
84
53
|
end
|
85
54
|
|
86
|
-
|
87
|
-
class ConnectionFailed < Error
|
55
|
+
class SSLError < ClientError
|
88
56
|
end
|
89
57
|
|
90
|
-
|
91
|
-
class SSLError < Error
|
92
|
-
end
|
58
|
+
class RetriableResponse < ClientError; end
|
93
59
|
|
94
|
-
|
95
|
-
|
60
|
+
[:ClientError, :ConnectionFailed, :ResourceNotFound,
|
61
|
+
:ParsingError, :TimeoutError, :SSLError, :RetriableResponse].each do |const|
|
62
|
+
Error.const_set(const, Faraday.const_get(const))
|
96
63
|
end
|
97
64
|
|
98
|
-
# Exception used to control the Retry middleware.
|
99
|
-
#
|
100
|
-
# @see Faraday::Request::Retry
|
101
|
-
class RetriableResponse < Error
|
102
|
-
end
|
103
65
|
|
104
|
-
%i[ClientError ConnectionFailed ResourceNotFound
|
105
|
-
ParsingError TimeoutError SSLError RetriableResponse].each do |const|
|
106
|
-
Error.const_set(
|
107
|
-
const,
|
108
|
-
Faraday::DeprecatedClass.proxy_class(
|
109
|
-
"Faraday::Error::#{const}",
|
110
|
-
Faraday.const_get(const)
|
111
|
-
)
|
112
|
-
)
|
113
|
-
end
|
114
66
|
end
|
data/lib/faraday/middleware.rb
CHANGED
@@ -1,10 +1,34 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Faraday
|
4
|
-
# Middleware is the basic base class of any Faraday middleware.
|
5
2
|
class Middleware
|
6
3
|
extend MiddlewareRegistry
|
7
|
-
|
4
|
+
|
5
|
+
class << self
|
6
|
+
attr_accessor :load_error
|
7
|
+
private :load_error=
|
8
|
+
end
|
9
|
+
|
10
|
+
self.load_error = nil
|
11
|
+
|
12
|
+
# Executes a block which should try to require and reference dependent libraries
|
13
|
+
def self.dependency(lib = nil)
|
14
|
+
lib ? require(lib) : yield
|
15
|
+
rescue LoadError, NameError => error
|
16
|
+
self.load_error = error
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.new(*)
|
20
|
+
raise "missing dependency for #{self}: #{load_error.message}" unless loaded?
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.loaded?
|
25
|
+
load_error.nil?
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.inherited(subclass)
|
29
|
+
super
|
30
|
+
subclass.send(:load_error=, self.load_error)
|
31
|
+
end
|
8
32
|
|
9
33
|
def initialize(app = nil)
|
10
34
|
@app = app
|
data/lib/faraday/options.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Faraday
|
4
2
|
# Subclasses Struct with some special helpers for converting from a Hash to
|
5
3
|
# a Struct.
|
@@ -12,7 +10,6 @@ module Faraday
|
|
12
10
|
# Public
|
13
11
|
def each
|
14
12
|
return to_enum(:each) unless block_given?
|
15
|
-
|
16
13
|
members.each do |key|
|
17
14
|
yield(key.to_sym, send(key))
|
18
15
|
end
|
@@ -30,7 +27,7 @@ module Faraday
|
|
30
27
|
new_value = value
|
31
28
|
end
|
32
29
|
|
33
|
-
send("#{key}=", new_value) unless new_value.nil?
|
30
|
+
self.send("#{key}=", new_value) unless new_value.nil?
|
34
31
|
end
|
35
32
|
self
|
36
33
|
end
|
@@ -50,14 +47,10 @@ module Faraday
|
|
50
47
|
# Public
|
51
48
|
def merge!(other)
|
52
49
|
other.each do |key, other_value|
|
53
|
-
self_value = send(key)
|
50
|
+
self_value = self.send(key)
|
54
51
|
sub_options = self.class.options_for(key)
|
55
|
-
new_value =
|
56
|
-
|
57
|
-
else
|
58
|
-
other_value
|
59
|
-
end
|
60
|
-
send("#{key}=", new_value) unless new_value.nil?
|
52
|
+
new_value = (self_value && sub_options && other_value) ? self_value.merge(other_value) : other_value
|
53
|
+
self.send("#{key}=", new_value) unless new_value.nil?
|
61
54
|
end
|
62
55
|
self
|
63
56
|
end
|
@@ -76,10 +69,10 @@ module Faraday
|
|
76
69
|
def fetch(key, *args)
|
77
70
|
unless symbolized_key_set.include?(key.to_sym)
|
78
71
|
key_setter = "#{key}="
|
79
|
-
if
|
72
|
+
if args.size > 0
|
80
73
|
send(key_setter, args.first)
|
81
74
|
elsif block_given?
|
82
|
-
send(key_setter,
|
75
|
+
send(key_setter, Proc.new.call(key))
|
83
76
|
else
|
84
77
|
raise self.class.fetch_error_class, "key not found: #{key.inspect}"
|
85
78
|
end
|
@@ -105,7 +98,6 @@ module Faraday
|
|
105
98
|
# Public
|
106
99
|
def each_key
|
107
100
|
return to_enum(:each_key) unless block_given?
|
108
|
-
|
109
101
|
keys.each do |key|
|
110
102
|
yield(key)
|
111
103
|
end
|
@@ -121,7 +113,6 @@ module Faraday
|
|
121
113
|
# Public
|
122
114
|
def each_value
|
123
115
|
return to_enum(:each_value) unless block_given?
|
124
|
-
|
125
116
|
values.each do |value|
|
126
117
|
yield(value)
|
127
118
|
end
|
@@ -151,9 +142,9 @@ module Faraday
|
|
151
142
|
value = send(member)
|
152
143
|
values << "#{member}=#{value.inspect}" if value
|
153
144
|
end
|
154
|
-
values = values.empty? ? '(empty)' : values.join(
|
145
|
+
values = values.empty? ? ' (empty)' : (' ' << values.join(", "))
|
155
146
|
|
156
|
-
%(#<#{self.class}
|
147
|
+
%(#<#{self.class}#{values}>)
|
157
148
|
end
|
158
149
|
|
159
150
|
# Internal
|
@@ -171,12 +162,8 @@ module Faraday
|
|
171
162
|
@attribute_options ||= {}
|
172
163
|
end
|
173
164
|
|
174
|
-
def self.memoized(key
|
175
|
-
|
176
|
-
raise ArgumentError, '#memoized must be called with a block'
|
177
|
-
end
|
178
|
-
|
179
|
-
memoized_attributes[key.to_sym] = block
|
165
|
+
def self.memoized(key)
|
166
|
+
memoized_attributes[key.to_sym] = Proc.new
|
180
167
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
181
168
|
def #{key}() self[:#{key}]; end
|
182
169
|
RUBY
|
@@ -188,7 +175,7 @@ module Faraday
|
|
188
175
|
|
189
176
|
def [](key)
|
190
177
|
key = key.to_sym
|
191
|
-
if
|
178
|
+
if method = self.class.memoized_attributes[key]
|
192
179
|
super(key) || (self[key] = instance_eval(&method))
|
193
180
|
else
|
194
181
|
super
|
@@ -196,7 +183,7 @@ module Faraday
|
|
196
183
|
end
|
197
184
|
|
198
185
|
def symbolized_key_set
|
199
|
-
@symbolized_key_set ||= Set.new(keys.map
|
186
|
+
@symbolized_key_set ||= Set.new(keys.map { |k| k.to_sym })
|
200
187
|
end
|
201
188
|
|
202
189
|
def self.inherited(subclass)
|
@@ -207,16 +194,180 @@ module Faraday
|
|
207
194
|
|
208
195
|
def self.fetch_error_class
|
209
196
|
@fetch_error_class ||= if Object.const_defined?(:KeyError)
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
197
|
+
::KeyError
|
198
|
+
else
|
199
|
+
::IndexError
|
200
|
+
end
|
214
201
|
end
|
215
202
|
end
|
216
|
-
end
|
217
203
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
204
|
+
class RequestOptions < Options.new(:params_encoder, :proxy, :bind,
|
205
|
+
:timeout, :open_timeout, :write_timeout, :boundary, :oauth, :context)
|
206
|
+
|
207
|
+
def []=(key, value)
|
208
|
+
if key && key.to_sym == :proxy
|
209
|
+
super(key, value ? ProxyOptions.from(value) : nil)
|
210
|
+
else
|
211
|
+
super(key, value)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
class SSLOptions < Options.new(:verify, :ca_file, :ca_path, :verify_mode,
|
217
|
+
:cert_store, :client_cert, :client_key, :certificate, :private_key, :verify_depth,
|
218
|
+
:version, :min_version, :max_version)
|
219
|
+
|
220
|
+
def verify?
|
221
|
+
verify != false
|
222
|
+
end
|
223
|
+
|
224
|
+
def disable?
|
225
|
+
!verify?
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
class ProxyOptions < Options.new(:uri, :user, :password)
|
230
|
+
extend Forwardable
|
231
|
+
def_delegators :uri, :scheme, :scheme=, :host, :host=, :port, :port=, :path, :path=
|
232
|
+
|
233
|
+
def self.from(value)
|
234
|
+
case value
|
235
|
+
when String
|
236
|
+
value = {:uri => Utils.URI(value)}
|
237
|
+
when URI
|
238
|
+
value = {:uri => value}
|
239
|
+
when Hash, Options
|
240
|
+
if uri = value.delete(:uri)
|
241
|
+
value[:uri] = Utils.URI(uri)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
super(value)
|
245
|
+
end
|
246
|
+
|
247
|
+
memoized(:user) { uri && uri.user && Utils.unescape(uri.user) }
|
248
|
+
memoized(:password) { uri && uri.password && Utils.unescape(uri.password) }
|
249
|
+
end
|
250
|
+
|
251
|
+
class ConnectionOptions < Options.new(:request, :proxy, :ssl, :builder, :url,
|
252
|
+
:parallel_manager, :params, :headers, :builder_class)
|
253
|
+
|
254
|
+
options :request => RequestOptions, :ssl => SSLOptions
|
255
|
+
|
256
|
+
memoized(:request) { self.class.options_for(:request).new }
|
257
|
+
|
258
|
+
memoized(:ssl) { self.class.options_for(:ssl).new }
|
259
|
+
|
260
|
+
memoized(:builder_class) { RackBuilder }
|
261
|
+
|
262
|
+
def new_builder(block)
|
263
|
+
builder_class.new(&block)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
class Env < Options.new(:method, :body, :url, :request, :request_headers,
|
268
|
+
:ssl, :parallel_manager, :params, :response, :response_headers, :status,
|
269
|
+
:reason_phrase)
|
270
|
+
|
271
|
+
ContentLength = 'Content-Length'.freeze
|
272
|
+
StatusesWithoutBody = Set.new [204, 304]
|
273
|
+
SuccessfulStatuses = 200..299
|
274
|
+
|
275
|
+
# A Set of HTTP verbs that typically send a body. If no body is set for
|
276
|
+
# these requests, the Content-Length header is set to 0.
|
277
|
+
MethodsWithBodies = Set.new [:post, :put, :patch, :options]
|
278
|
+
|
279
|
+
options :request => RequestOptions,
|
280
|
+
:request_headers => Utils::Headers, :response_headers => Utils::Headers
|
281
|
+
|
282
|
+
extend Forwardable
|
283
|
+
|
284
|
+
def_delegators :request, :params_encoder
|
285
|
+
|
286
|
+
# Public
|
287
|
+
def self.from(value)
|
288
|
+
env = super(value)
|
289
|
+
if value.respond_to?(:custom_members)
|
290
|
+
env.custom_members.update(value.custom_members)
|
291
|
+
end
|
292
|
+
env
|
293
|
+
end
|
294
|
+
|
295
|
+
# Public
|
296
|
+
def [](key)
|
297
|
+
if in_member_set?(key)
|
298
|
+
super(key)
|
299
|
+
else
|
300
|
+
custom_members[key]
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
# Public
|
305
|
+
def []=(key, value)
|
306
|
+
if in_member_set?(key)
|
307
|
+
super(key, value)
|
308
|
+
else
|
309
|
+
custom_members[key] = value
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
# Public
|
314
|
+
def success?
|
315
|
+
SuccessfulStatuses.include?(status)
|
316
|
+
end
|
317
|
+
|
318
|
+
# Public
|
319
|
+
def needs_body?
|
320
|
+
!body && MethodsWithBodies.include?(method)
|
321
|
+
end
|
322
|
+
|
323
|
+
# Public
|
324
|
+
def clear_body
|
325
|
+
request_headers[ContentLength] = '0'
|
326
|
+
self.body = ''
|
327
|
+
end
|
328
|
+
|
329
|
+
# Public
|
330
|
+
def parse_body?
|
331
|
+
!StatusesWithoutBody.include?(status)
|
332
|
+
end
|
333
|
+
|
334
|
+
# Public
|
335
|
+
def parallel?
|
336
|
+
!!parallel_manager
|
337
|
+
end
|
338
|
+
|
339
|
+
def inspect
|
340
|
+
attrs = [nil]
|
341
|
+
members.each do |mem|
|
342
|
+
if value = send(mem)
|
343
|
+
attrs << "@#{mem}=#{value.inspect}"
|
344
|
+
end
|
345
|
+
end
|
346
|
+
if !custom_members.empty?
|
347
|
+
attrs << "@custom=#{custom_members.inspect}"
|
348
|
+
end
|
349
|
+
%(#<#{self.class}#{attrs.join(" ")}>)
|
350
|
+
end
|
351
|
+
|
352
|
+
# Internal
|
353
|
+
def custom_members
|
354
|
+
@custom_members ||= {}
|
355
|
+
end
|
356
|
+
|
357
|
+
# Internal
|
358
|
+
if members.first.is_a?(Symbol)
|
359
|
+
def in_member_set?(key)
|
360
|
+
self.class.member_set.include?(key.to_sym)
|
361
|
+
end
|
362
|
+
else
|
363
|
+
def in_member_set?(key)
|
364
|
+
self.class.member_set.include?(key.to_s)
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
# Internal
|
369
|
+
def self.member_set
|
370
|
+
@member_set ||= Set.new(members)
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|