faraday 1.4.1 → 2.7.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +197 -3
- data/LICENSE.md +1 -1
- data/README.md +18 -16
- data/examples/client_spec.rb +67 -13
- data/examples/client_test.rb +80 -15
- data/lib/faraday/adapter/test.rb +117 -52
- data/lib/faraday/adapter.rb +5 -14
- data/lib/faraday/connection.rb +64 -119
- data/lib/faraday/encoders/nested_params_encoder.rb +13 -6
- data/lib/faraday/error.rb +3 -8
- data/lib/faraday/logging/formatter.rb +19 -2
- data/lib/faraday/middleware.rb +3 -1
- data/lib/faraday/middleware_registry.rb +17 -63
- data/lib/faraday/options/env.rb +31 -7
- data/lib/faraday/options/proxy_options.rb +4 -0
- data/lib/faraday/options/ssl_options.rb +11 -1
- data/lib/faraday/options.rb +3 -3
- data/lib/faraday/rack_builder.rb +23 -20
- data/lib/faraday/request/authorization.rb +37 -38
- data/lib/faraday/request/instrumentation.rb +2 -0
- data/lib/faraday/request/json.rb +55 -0
- data/lib/faraday/request/url_encoded.rb +5 -1
- data/lib/faraday/request.rb +12 -32
- data/lib/faraday/response/json.rb +54 -0
- data/lib/faraday/response/logger.rb +8 -4
- data/lib/faraday/response/raise_error.rb +9 -1
- data/lib/faraday/response.rb +10 -20
- data/lib/faraday/utils/headers.rb +7 -2
- data/lib/faraday/utils.rb +10 -5
- data/lib/faraday/version.rb +1 -1
- data/lib/faraday.rb +10 -31
- data/spec/faraday/adapter/test_spec.rb +182 -0
- data/spec/faraday/connection_spec.rb +177 -90
- data/spec/faraday/middleware_registry_spec.rb +31 -0
- data/spec/faraday/middleware_spec.rb +18 -0
- data/spec/faraday/options/env_spec.rb +8 -2
- data/spec/faraday/options/proxy_options_spec.rb +7 -0
- data/spec/faraday/params_encoders/nested_spec.rb +8 -0
- data/spec/faraday/rack_builder_spec.rb +26 -54
- data/spec/faraday/request/authorization_spec.rb +54 -24
- data/spec/faraday/request/instrumentation_spec.rb +5 -7
- data/spec/faraday/request/json_spec.rb +111 -0
- data/spec/faraday/request/url_encoded_spec.rb +12 -2
- data/spec/faraday/request_spec.rb +5 -15
- data/spec/faraday/response/json_spec.rb +117 -0
- data/spec/faraday/response/logger_spec.rb +28 -0
- data/spec/faraday/response/raise_error_spec.rb +7 -4
- data/spec/faraday/response_spec.rb +3 -1
- data/spec/faraday/utils/headers_spec.rb +22 -4
- data/spec/faraday/utils_spec.rb +63 -1
- data/spec/support/fake_safe_buffer.rb +1 -1
- data/spec/support/helper_methods.rb +0 -37
- data/spec/support/shared_examples/adapter.rb +2 -2
- data/spec/support/shared_examples/request_method.rb +22 -21
- metadata +14 -80
- data/lib/faraday/adapter/em_http.rb +0 -289
- data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -62
- data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -69
- data/lib/faraday/adapter/em_synchrony.rb +0 -153
- data/lib/faraday/adapter/httpclient.rb +0 -152
- data/lib/faraday/adapter/patron.rb +0 -132
- data/lib/faraday/adapter/rack.rb +0 -75
- data/lib/faraday/adapter/typhoeus.rb +0 -15
- data/lib/faraday/autoload.rb +0 -92
- data/lib/faraday/dependency_loader.rb +0 -37
- data/lib/faraday/file_part.rb +0 -128
- data/lib/faraday/param_part.rb +0 -53
- data/lib/faraday/request/basic_authentication.rb +0 -20
- data/lib/faraday/request/multipart.rb +0 -106
- data/lib/faraday/request/retry.rb +0 -239
- data/lib/faraday/request/token_authentication.rb +0 -20
- data/spec/faraday/adapter/em_http_spec.rb +0 -47
- data/spec/faraday/adapter/em_synchrony_spec.rb +0 -16
- data/spec/faraday/adapter/excon_spec.rb +0 -49
- data/spec/faraday/adapter/httpclient_spec.rb +0 -73
- data/spec/faraday/adapter/net_http_spec.rb +0 -64
- data/spec/faraday/adapter/patron_spec.rb +0 -18
- data/spec/faraday/adapter/rack_spec.rb +0 -8
- data/spec/faraday/adapter/typhoeus_spec.rb +0 -7
- data/spec/faraday/composite_read_io_spec.rb +0 -80
- data/spec/faraday/request/multipart_spec.rb +0 -302
- data/spec/faraday/request/retry_spec.rb +0 -242
- data/spec/faraday/response/middleware_spec.rb +0 -68
- data/spec/support/webmock_rack_app.rb +0 -68
data/lib/faraday/connection.rb
CHANGED
@@ -6,15 +6,16 @@ module Faraday
|
|
6
6
|
#
|
7
7
|
# @example
|
8
8
|
#
|
9
|
-
# conn = Faraday::Connection.new 'http://
|
9
|
+
# conn = Faraday::Connection.new 'http://httpbingo.org'
|
10
10
|
#
|
11
|
-
# # GET http://
|
11
|
+
# # GET http://httpbingo.org/nigiri
|
12
12
|
# conn.get 'nigiri'
|
13
13
|
# # => #<Faraday::Response>
|
14
14
|
#
|
15
15
|
class Connection
|
16
16
|
# A Set of allowed HTTP verbs.
|
17
17
|
METHODS = Set.new %i[get post put delete head patch options trace]
|
18
|
+
USER_AGENT = "Faraday v#{VERSION}"
|
18
19
|
|
19
20
|
# @return [Hash] URI query unencoded key/value pairs.
|
20
21
|
attr_reader :params
|
@@ -26,7 +27,7 @@ module Faraday
|
|
26
27
|
# Connection. This includes a default host name, scheme, port, and path.
|
27
28
|
attr_reader :url_prefix
|
28
29
|
|
29
|
-
# @return [Faraday::
|
30
|
+
# @return [Faraday::RackBuilder] Builder for this Connection.
|
30
31
|
attr_reader :builder
|
31
32
|
|
32
33
|
# @return [Hash] SSL options.
|
@@ -63,7 +64,7 @@ module Faraday
|
|
63
64
|
options = ConnectionOptions.from(options)
|
64
65
|
|
65
66
|
if url.is_a?(Hash) || url.is_a?(ConnectionOptions)
|
66
|
-
options =
|
67
|
+
options = Utils.deep_merge(options, url)
|
67
68
|
url = options.url
|
68
69
|
end
|
69
70
|
|
@@ -73,6 +74,7 @@ module Faraday
|
|
73
74
|
@options = options.request
|
74
75
|
@ssl = options.ssl
|
75
76
|
@default_parallel_manager = options.parallel_manager
|
77
|
+
@manual_proxy = nil
|
76
78
|
|
77
79
|
@builder = options.builder || begin
|
78
80
|
# pass an empty block to Builder so it doesn't assume default middleware
|
@@ -88,7 +90,7 @@ module Faraday
|
|
88
90
|
|
89
91
|
yield(self) if block_given?
|
90
92
|
|
91
|
-
@headers[:user_agent] ||=
|
93
|
+
@headers[:user_agent] ||= USER_AGENT
|
92
94
|
end
|
93
95
|
|
94
96
|
def initialize_proxy(url, options)
|
@@ -115,7 +117,7 @@ module Faraday
|
|
115
117
|
|
116
118
|
extend Forwardable
|
117
119
|
|
118
|
-
def_delegators :builder, :
|
120
|
+
def_delegators :builder, :use, :request, :response, :adapter, :app
|
119
121
|
|
120
122
|
# Closes the underlying resources and/or connections. In the case of
|
121
123
|
# persistent connections, this closes all currently open connections
|
@@ -128,10 +130,10 @@ module Faraday
|
|
128
130
|
# Makes a GET HTTP request without a body.
|
129
131
|
# @!scope class
|
130
132
|
#
|
131
|
-
# @param url [String] The optional String base URL to use as a prefix for
|
133
|
+
# @param url [String, URI, nil] The optional String base URL to use as a prefix for
|
132
134
|
# all requests. Can also be the options Hash.
|
133
|
-
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
134
|
-
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
135
|
+
# @param params [Hash, nil] Hash of URI query unencoded key/value pairs.
|
136
|
+
# @param headers [Hash, nil] unencoded HTTP header key/value pairs.
|
135
137
|
#
|
136
138
|
# @example
|
137
139
|
# conn.get '/items', { page: 1 }, :accept => 'application/json'
|
@@ -150,10 +152,10 @@ module Faraday
|
|
150
152
|
# Makes a HEAD HTTP request without a body.
|
151
153
|
# @!scope class
|
152
154
|
#
|
153
|
-
# @param url [String] The optional String base URL to use as a prefix for
|
155
|
+
# @param url [String, URI, nil] The optional String base URL to use as a prefix for
|
154
156
|
# all requests. Can also be the options Hash.
|
155
|
-
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
156
|
-
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
157
|
+
# @param params [Hash, nil] Hash of URI query unencoded key/value pairs.
|
158
|
+
# @param headers [Hash, nil] unencoded HTTP header key/value pairs.
|
157
159
|
#
|
158
160
|
# @example
|
159
161
|
# conn.head '/items/1'
|
@@ -165,10 +167,10 @@ module Faraday
|
|
165
167
|
# Makes a DELETE HTTP request without a body.
|
166
168
|
# @!scope class
|
167
169
|
#
|
168
|
-
# @param url [String] The optional String base URL to use as a prefix for
|
170
|
+
# @param url [String, URI, nil] The optional String base URL to use as a prefix for
|
169
171
|
# all requests. Can also be the options Hash.
|
170
|
-
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
171
|
-
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
172
|
+
# @param params [Hash, nil] Hash of URI query unencoded key/value pairs.
|
173
|
+
# @param headers [Hash, nil] unencoded HTTP header key/value pairs.
|
172
174
|
#
|
173
175
|
# @example
|
174
176
|
# conn.delete '/items/1'
|
@@ -180,10 +182,10 @@ module Faraday
|
|
180
182
|
# Makes a TRACE HTTP request without a body.
|
181
183
|
# @!scope class
|
182
184
|
#
|
183
|
-
# @param url [String] The optional String base URL to use as a prefix for
|
185
|
+
# @param url [String, URI, nil] The optional String base URL to use as a prefix for
|
184
186
|
# all requests. Can also be the options Hash.
|
185
|
-
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
186
|
-
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
187
|
+
# @param params [Hash, nil] Hash of URI query unencoded key/value pairs.
|
188
|
+
# @param headers [Hash, nil] unencoded HTTP header key/value pairs.
|
187
189
|
#
|
188
190
|
# @example
|
189
191
|
# conn.connect '/items/1'
|
@@ -208,9 +210,9 @@ module Faraday
|
|
208
210
|
#
|
209
211
|
# @overload options(url, params = nil, headers = nil)
|
210
212
|
# Makes an OPTIONS HTTP request to the given URL.
|
211
|
-
# @param url [String] String base URL to sue as a prefix for all requests.
|
212
|
-
# @param params [Hash] Hash of URI query unencoded key/value pairs.
|
213
|
-
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
213
|
+
# @param url [String, URI, nil] String base URL to sue as a prefix for all requests.
|
214
|
+
# @param params [Hash, nil] Hash of URI query unencoded key/value pairs.
|
215
|
+
# @param headers [Hash, nil] unencoded HTTP header key/value pairs.
|
214
216
|
#
|
215
217
|
# @example
|
216
218
|
# conn.options '/items/1'
|
@@ -218,7 +220,7 @@ module Faraday
|
|
218
220
|
# @yield [Faraday::Request] for further request customizations
|
219
221
|
# @return [Faraday::Response]
|
220
222
|
def options(*args)
|
221
|
-
return @options if args.
|
223
|
+
return @options if args.empty?
|
222
224
|
|
223
225
|
url, params, headers = *args
|
224
226
|
run_request(:options, url, nil, headers) do |request|
|
@@ -231,10 +233,10 @@ module Faraday
|
|
231
233
|
# Makes a POST HTTP request with a body.
|
232
234
|
# @!scope class
|
233
235
|
#
|
234
|
-
# @param url [String] The optional String base URL to use as a prefix for
|
236
|
+
# @param url [String, URI, nil] The optional String base URL to use as a prefix for
|
235
237
|
# all requests. Can also be the options Hash.
|
236
|
-
# @param body [String] body for the request.
|
237
|
-
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
238
|
+
# @param body [String, nil] body for the request.
|
239
|
+
# @param headers [Hash, nil] unencoded HTTP header key/value pairs.
|
238
240
|
#
|
239
241
|
# @example
|
240
242
|
# conn.post '/items', data, content_type: 'application/json'
|
@@ -253,20 +255,19 @@ module Faraday
|
|
253
255
|
# Makes a PUT HTTP request with a body.
|
254
256
|
# @!scope class
|
255
257
|
#
|
256
|
-
# @param url [String] The optional String base URL to use as a prefix for
|
258
|
+
# @param url [String, URI, nil] The optional String base URL to use as a prefix for
|
257
259
|
# all requests. Can also be the options Hash.
|
258
|
-
# @param body [String] body for the request.
|
259
|
-
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
260
|
+
# @param body [String, nil] body for the request.
|
261
|
+
# @param headers [Hash, nil] unencoded HTTP header key/value pairs.
|
260
262
|
#
|
261
263
|
# @example
|
262
|
-
#
|
263
|
-
# conn.post '/items', data, content_type: 'application/json'
|
264
|
+
# conn.put '/products/123', data, content_type: 'application/json'
|
264
265
|
#
|
265
|
-
# #
|
266
|
-
# conn.
|
267
|
-
# req.headers[
|
268
|
-
# req.
|
269
|
-
# req.
|
266
|
+
# # Star a gist.
|
267
|
+
# conn.put 'https://api.github.com/gists/GIST_ID/star' do |req|
|
268
|
+
# req.headers['Accept'] = 'application/vnd.github+json'
|
269
|
+
# req.headers['Authorization'] = 'Bearer <YOUR-TOKEN>'
|
270
|
+
# req.headers['X-GitHub-Api-Version'] = '2022-11-28'
|
270
271
|
# end
|
271
272
|
#
|
272
273
|
# @yield [Faraday::Request] for further request customizations
|
@@ -281,62 +282,6 @@ module Faraday
|
|
281
282
|
RUBY
|
282
283
|
end
|
283
284
|
|
284
|
-
# Sets up the Authorization header with these credentials, encoded
|
285
|
-
# with base64.
|
286
|
-
#
|
287
|
-
# @param login [String] The authentication login.
|
288
|
-
# @param pass [String] The authentication password.
|
289
|
-
#
|
290
|
-
# @example
|
291
|
-
#
|
292
|
-
# conn.basic_auth 'Aladdin', 'open sesame'
|
293
|
-
# conn.headers['Authorization']
|
294
|
-
# # => "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="
|
295
|
-
#
|
296
|
-
# @return [void]
|
297
|
-
def basic_auth(login, pass)
|
298
|
-
set_authorization_header(:basic_auth, login, pass)
|
299
|
-
end
|
300
|
-
|
301
|
-
# Sets up the Authorization header with the given token.
|
302
|
-
#
|
303
|
-
# @param token [String]
|
304
|
-
# @param options [Hash] extra token options.
|
305
|
-
#
|
306
|
-
# @example
|
307
|
-
#
|
308
|
-
# conn.token_auth 'abcdef', foo: 'bar'
|
309
|
-
# conn.headers['Authorization']
|
310
|
-
# # => "Token token=\"abcdef\",
|
311
|
-
# foo=\"bar\""
|
312
|
-
#
|
313
|
-
# @return [void]
|
314
|
-
def token_auth(token, options = nil)
|
315
|
-
set_authorization_header(:token_auth, token, options)
|
316
|
-
end
|
317
|
-
|
318
|
-
# Sets up a custom Authorization header.
|
319
|
-
#
|
320
|
-
# @param type [String] authorization type
|
321
|
-
# @param token [String, Hash] token. A String value is taken literally, and
|
322
|
-
# a Hash is encoded into comma-separated key/value pairs.
|
323
|
-
#
|
324
|
-
# @example
|
325
|
-
#
|
326
|
-
# conn.authorization :Bearer, 'mF_9.B5f-4.1JqM'
|
327
|
-
# conn.headers['Authorization']
|
328
|
-
# # => "Bearer mF_9.B5f-4.1JqM"
|
329
|
-
#
|
330
|
-
# conn.authorization :Token, token: 'abcdef', foo: 'bar'
|
331
|
-
# conn.headers['Authorization']
|
332
|
-
# # => "Token token=\"abcdef\",
|
333
|
-
# foo=\"bar\""
|
334
|
-
#
|
335
|
-
# @return [void]
|
336
|
-
def authorization(type, token)
|
337
|
-
set_authorization_header(:authorization, type, token)
|
338
|
-
end
|
339
|
-
|
340
285
|
# Check if the adapter is parallel-capable.
|
341
286
|
#
|
342
287
|
# @yield if the adapter isn't parallel-capable, or if no adapter is set yet.
|
@@ -403,11 +348,11 @@ module Faraday
|
|
403
348
|
# @example
|
404
349
|
#
|
405
350
|
# conn = Faraday::Connection.new { ... }
|
406
|
-
# conn.url_prefix = "https://
|
351
|
+
# conn.url_prefix = "https://httpbingo.org/api"
|
407
352
|
# conn.scheme # => https
|
408
353
|
# conn.path_prefix # => "/api"
|
409
354
|
#
|
410
|
-
# conn.get("nigiri?page=2") # accesses https://
|
355
|
+
# conn.get("nigiri?page=2") # accesses https://httpbingo.org/api/nigiri
|
411
356
|
def url_prefix=(url, encoder = nil)
|
412
357
|
uri = @url_prefix = Utils.URI(url)
|
413
358
|
self.path_prefix = uri.path
|
@@ -416,9 +361,16 @@ module Faraday
|
|
416
361
|
uri.query = nil
|
417
362
|
|
418
363
|
with_uri_credentials(uri) do |user, password|
|
419
|
-
|
364
|
+
set_basic_auth(user, password)
|
420
365
|
uri.user = uri.password = nil
|
421
366
|
end
|
367
|
+
|
368
|
+
@proxy = proxy_from_env(url) unless @manual_proxy
|
369
|
+
end
|
370
|
+
|
371
|
+
def set_basic_auth(user, password)
|
372
|
+
header = Faraday::Utils.basic_header_from(user, password)
|
373
|
+
headers[Faraday::Request::Authorization::KEY] = header
|
422
374
|
end
|
423
375
|
|
424
376
|
# Sets the path prefix and ensures that it always has a leading
|
@@ -437,20 +389,20 @@ module Faraday
|
|
437
389
|
# Takes a relative url for a request and combines it with the defaults
|
438
390
|
# set on the connection instance.
|
439
391
|
#
|
440
|
-
# @param url [String]
|
392
|
+
# @param url [String, URI, nil]
|
441
393
|
# @param extra_params [Hash]
|
442
394
|
#
|
443
395
|
# @example
|
444
396
|
# conn = Faraday::Connection.new { ... }
|
445
|
-
# conn.url_prefix = "https://
|
397
|
+
# conn.url_prefix = "https://httpbingo.org/api?token=abc"
|
446
398
|
# conn.scheme # => https
|
447
399
|
# conn.path_prefix # => "/api"
|
448
400
|
#
|
449
401
|
# conn.build_url("nigiri?page=2")
|
450
|
-
# # => https://
|
402
|
+
# # => https://httpbingo.org/api/nigiri?token=abc&page=2
|
451
403
|
#
|
452
404
|
# conn.build_url("nigiri", page: 2)
|
453
|
-
# # => https://
|
405
|
+
# # => https://httpbingo.org/api/nigiri?token=abc&page=2
|
454
406
|
#
|
455
407
|
def build_url(url = nil, extra_params = nil)
|
456
408
|
uri = build_exclusive_url(url)
|
@@ -470,10 +422,10 @@ module Faraday
|
|
470
422
|
# Builds and runs the Faraday::Request.
|
471
423
|
#
|
472
424
|
# @param method [Symbol] HTTP method.
|
473
|
-
# @param url [String, URI] String or URI to access.
|
474
|
-
# @param body [
|
425
|
+
# @param url [String, URI, nil] String or URI to access.
|
426
|
+
# @param body [String, nil] The request body that will eventually be converted to
|
475
427
|
# a string.
|
476
|
-
# @param headers [Hash] unencoded HTTP header key/value pairs.
|
428
|
+
# @param headers [Hash, nil] unencoded HTTP header key/value pairs.
|
477
429
|
#
|
478
430
|
# @return [Faraday::Response]
|
479
431
|
def run_request(method, url, body, headers)
|
@@ -509,7 +461,7 @@ module Faraday
|
|
509
461
|
|
510
462
|
# Build an absolute URL based on url_prefix.
|
511
463
|
#
|
512
|
-
# @param url [String, URI]
|
464
|
+
# @param url [String, URI, nil]
|
513
465
|
# @param params [Faraday::Utils::ParamsHash] A Faraday::Utils::ParamsHash to
|
514
466
|
# replace the query values
|
515
467
|
# of the resulting url (default: nil).
|
@@ -517,19 +469,16 @@ module Faraday
|
|
517
469
|
# @return [URI]
|
518
470
|
def build_exclusive_url(url = nil, params = nil, params_encoder = nil)
|
519
471
|
url = nil if url.respond_to?(:empty?) && url.empty?
|
520
|
-
base = url_prefix
|
521
|
-
if url && base.path
|
522
|
-
base = base.dup
|
472
|
+
base = url_prefix.dup
|
473
|
+
if url && !base.path.end_with?('/')
|
523
474
|
base.path = "#{base.path}/" # ensure trailing slash
|
524
475
|
end
|
525
|
-
url = url
|
476
|
+
url = url.to_s.gsub(':', '%3A') if URI.parse(url.to_s).opaque
|
526
477
|
uri = url ? base + url : base
|
527
478
|
if params
|
528
479
|
uri.query = params.to_query(params_encoder || options.params_encoder)
|
529
480
|
end
|
530
|
-
# rubocop:disable Style/SafeNavigation
|
531
481
|
uri.query = nil if uri.query && uri.query.empty?
|
532
|
-
# rubocop:enable Style/SafeNavigation
|
533
482
|
uri
|
534
483
|
end
|
535
484
|
|
@@ -561,14 +510,6 @@ module Faraday
|
|
561
510
|
yield(Utils.unescape(uri.user), Utils.unescape(uri.password))
|
562
511
|
end
|
563
512
|
|
564
|
-
def set_authorization_header(header_type, *args)
|
565
|
-
header = Faraday::Request
|
566
|
-
.lookup_middleware(header_type)
|
567
|
-
.header(*args)
|
568
|
-
|
569
|
-
headers[Faraday::Request::Authorization::KEY] = header
|
570
|
-
end
|
571
|
-
|
572
513
|
def proxy_from_env(url)
|
573
514
|
return if Faraday.ignore_env_proxy
|
574
515
|
|
@@ -577,7 +518,11 @@ module Faraday
|
|
577
518
|
case url
|
578
519
|
when String
|
579
520
|
uri = Utils.URI(url)
|
580
|
-
uri =
|
521
|
+
uri = if uri.host.nil?
|
522
|
+
find_default_proxy
|
523
|
+
else
|
524
|
+
URI.parse("#{uri.scheme}://#{uri.host}").find_proxy
|
525
|
+
end
|
581
526
|
when URI
|
582
527
|
uri = url.find_proxy
|
583
528
|
when nil
|
@@ -591,7 +536,7 @@ module Faraday
|
|
591
536
|
end
|
592
537
|
|
593
538
|
def find_default_proxy
|
594
|
-
uri = ENV
|
539
|
+
uri = ENV.fetch('http_proxy', nil)
|
595
540
|
return unless uri && !uri.empty?
|
596
541
|
|
597
542
|
uri = "http://#{uri}" unless uri.match?(/^http/i)
|
@@ -609,7 +554,7 @@ module Faraday
|
|
609
554
|
end
|
610
555
|
|
611
556
|
def support_parallel?(adapter)
|
612
|
-
adapter
|
557
|
+
adapter.respond_to?(:supports_parallel?) && adapter&.supports_parallel?
|
613
558
|
end
|
614
559
|
end
|
615
560
|
end
|
@@ -62,11 +62,17 @@ module Faraday
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def encode_array(parent, value)
|
65
|
-
|
66
|
-
return new_parent if value.empty?
|
65
|
+
return "#{parent}%5B%5D" if value.empty?
|
67
66
|
|
68
67
|
buffer = +''
|
69
|
-
value.
|
68
|
+
value.each_with_index do |val, index|
|
69
|
+
new_parent = if @array_indices
|
70
|
+
"#{parent}%5B#{index}%5D"
|
71
|
+
else
|
72
|
+
"#{parent}%5B%5D"
|
73
|
+
end
|
74
|
+
buffer << "#{encode_pair(new_parent, val)}&"
|
75
|
+
end
|
70
76
|
buffer.chop
|
71
77
|
end
|
72
78
|
end
|
@@ -102,7 +108,7 @@ module Faraday
|
|
102
108
|
subkeys = key.scan(SUBKEYS_REGEX)
|
103
109
|
subkeys.each_with_index do |subkey, i|
|
104
110
|
is_array = subkey =~ /[\[\]]+\Z/
|
105
|
-
subkey =
|
111
|
+
subkey = Regexp.last_match.pre_match if is_array
|
106
112
|
last_subkey = i == subkeys.length - 1
|
107
113
|
|
108
114
|
context = prepare_context(context, subkey, is_array, last_subkey)
|
@@ -124,7 +130,7 @@ module Faraday
|
|
124
130
|
value_type = is_array ? Array : Hash
|
125
131
|
if context[subkey] && !context[subkey].is_a?(value_type)
|
126
132
|
raise TypeError, "expected #{value_type.name} " \
|
127
|
-
|
133
|
+
"(got #{context[subkey].class.name}) for param `#{subkey}'"
|
128
134
|
end
|
129
135
|
|
130
136
|
context[subkey] ||= value_type.new
|
@@ -161,7 +167,7 @@ module Faraday
|
|
161
167
|
# for your requests.
|
162
168
|
module NestedParamsEncoder
|
163
169
|
class << self
|
164
|
-
attr_accessor :sort_params
|
170
|
+
attr_accessor :sort_params, :array_indices
|
165
171
|
|
166
172
|
extend Forwardable
|
167
173
|
def_delegators :'Faraday::Utils', :escape, :unescape
|
@@ -169,6 +175,7 @@ module Faraday
|
|
169
175
|
|
170
176
|
# Useful default for OAuth and caching.
|
171
177
|
@sort_params = true
|
178
|
+
@array_indices = false
|
172
179
|
|
173
180
|
extend EncodeMethods
|
174
181
|
extend DecodeMethods
|
data/lib/faraday/error.rb
CHANGED
@@ -6,7 +6,7 @@ module Faraday
|
|
6
6
|
class Error < StandardError
|
7
7
|
attr_reader :response, :wrapped_exception
|
8
8
|
|
9
|
-
def initialize(exc, response = nil)
|
9
|
+
def initialize(exc = nil, response = nil)
|
10
10
|
@wrapped_exception = nil unless defined?(@wrapped_exception)
|
11
11
|
@response = nil unless defined?(@response)
|
12
12
|
super(exc_msg_and_response!(exc, response))
|
@@ -52,6 +52,7 @@ module Faraday
|
|
52
52
|
# :body - Optional string HTTP response body.
|
53
53
|
# :request - Hash
|
54
54
|
# :method - Symbol with the request HTTP method.
|
55
|
+
# :url - URI object with the url requested.
|
55
56
|
# :url_path - String with the url path requested.
|
56
57
|
# :params - String key/value hash of query params
|
57
58
|
# present in the request.
|
@@ -140,13 +141,7 @@ module Faraday
|
|
140
141
|
class SSLError < Error
|
141
142
|
end
|
142
143
|
|
143
|
-
# Raised by
|
144
|
+
# Raised by middlewares that parse the response, like the JSON response middleware.
|
144
145
|
class ParsingError < Error
|
145
146
|
end
|
146
|
-
|
147
|
-
# Exception used to control the Retry middleware.
|
148
|
-
#
|
149
|
-
# @see Faraday::Request::Retry
|
150
|
-
class RetriableResponse < Error
|
151
|
-
end
|
152
147
|
end
|
@@ -1,13 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'pp'
|
3
|
+
require 'pp' # rubocop:disable Lint/RedundantRequireStatement
|
4
|
+
|
4
5
|
module Faraday
|
5
6
|
module Logging
|
6
7
|
# Serves as an integration point to customize logging
|
7
8
|
class Formatter
|
8
9
|
extend Forwardable
|
9
10
|
|
10
|
-
DEFAULT_OPTIONS = { headers: true, bodies: false,
|
11
|
+
DEFAULT_OPTIONS = { headers: true, bodies: false, errors: false,
|
11
12
|
log_level: :info }.freeze
|
12
13
|
|
13
14
|
def initialize(logger:, options:)
|
@@ -36,6 +37,18 @@ module Faraday
|
|
36
37
|
log_body('response', env[:body]) if env[:body] && log_body?(:response)
|
37
38
|
end
|
38
39
|
|
40
|
+
def exception(exc)
|
41
|
+
return unless log_errors?
|
42
|
+
|
43
|
+
error_log = proc { exc.full_message }
|
44
|
+
public_send(log_level, 'error', &error_log)
|
45
|
+
|
46
|
+
log_headers('error', exc.response_headers) if exc.respond_to?(:response_headers) && log_headers?(:error)
|
47
|
+
return unless exc.respond_to?(:response_body) && exc.response_body && log_body?(:error)
|
48
|
+
|
49
|
+
log_body('error', exc.response_body)
|
50
|
+
end
|
51
|
+
|
39
52
|
def filter(filter_word, filter_replacement)
|
40
53
|
@filter.push([filter_word, filter_replacement])
|
41
54
|
end
|
@@ -76,6 +89,10 @@ module Faraday
|
|
76
89
|
end
|
77
90
|
end
|
78
91
|
|
92
|
+
def log_errors?
|
93
|
+
@options[:errors]
|
94
|
+
end
|
95
|
+
|
79
96
|
def apply_filters(output)
|
80
97
|
@filter.each do |pattern, replacement|
|
81
98
|
output = output.to_s.gsub(pattern, replacement)
|
data/lib/faraday/middleware.rb
CHANGED
@@ -4,7 +4,6 @@ module Faraday
|
|
4
4
|
# Middleware is the basic base class of any Faraday middleware.
|
5
5
|
class Middleware
|
6
6
|
extend MiddlewareRegistry
|
7
|
-
extend DependencyLoader
|
8
7
|
|
9
8
|
attr_reader :app, :options
|
10
9
|
|
@@ -18,6 +17,9 @@ module Faraday
|
|
18
17
|
app.call(env).on_complete do |environment|
|
19
18
|
on_complete(environment) if respond_to?(:on_complete)
|
20
19
|
end
|
20
|
+
rescue StandardError => e
|
21
|
+
on_error(e) if respond_to?(:on_error)
|
22
|
+
raise
|
21
23
|
end
|
22
24
|
|
23
25
|
def close
|
@@ -6,59 +6,26 @@ module Faraday
|
|
6
6
|
# Adds the ability for other modules to register and lookup
|
7
7
|
# middleware classes.
|
8
8
|
module MiddlewareRegistry
|
9
|
+
def registered_middleware
|
10
|
+
@registered_middleware ||= {}
|
11
|
+
end
|
12
|
+
|
9
13
|
# Register middleware class(es) on the current module.
|
10
14
|
#
|
11
|
-
# @param
|
12
|
-
# @param mapping [Hash{
|
13
|
-
# Symbol => Module,
|
14
|
-
# Symbol => Array<Module, Symbol, String>,
|
15
|
-
# }] Middleware mapping from a lookup symbol to a reference to the
|
16
|
-
# middleware.
|
17
|
-
# Classes can be expressed as:
|
18
|
-
# - a fully qualified constant
|
19
|
-
# - a Symbol
|
20
|
-
# - a Proc that will be lazily called to return the former
|
21
|
-
# - an array is given, its first element is the constant or symbol,
|
22
|
-
# and its second is a file to `require`.
|
15
|
+
# @param mappings [Hash] Middleware mappings from a lookup symbol to a middleware class.
|
23
16
|
# @return [void]
|
24
17
|
#
|
25
18
|
# @example Lookup by a constant
|
26
19
|
#
|
27
20
|
# module Faraday
|
28
|
-
# class Whatever
|
21
|
+
# class Whatever < Middleware
|
29
22
|
# # Middleware looked up by :foo returns Faraday::Whatever::Foo.
|
30
|
-
# register_middleware
|
31
|
-
# end
|
32
|
-
# end
|
33
|
-
#
|
34
|
-
# @example Lookup by a symbol
|
35
|
-
#
|
36
|
-
# module Faraday
|
37
|
-
# class Whatever
|
38
|
-
# # Middleware looked up by :bar returns
|
39
|
-
# # Faraday::Whatever.const_get(:Bar)
|
40
|
-
# register_middleware bar: :Bar
|
41
|
-
# end
|
42
|
-
# end
|
43
|
-
#
|
44
|
-
# @example Lookup by a symbol and string in an array
|
45
|
-
#
|
46
|
-
# module Faraday
|
47
|
-
# class Whatever
|
48
|
-
# # Middleware looked up by :baz requires 'baz' and returns
|
49
|
-
# # Faraday::Whatever.const_get(:Baz)
|
50
|
-
# register_middleware baz: [:Baz, 'baz']
|
23
|
+
# register_middleware(foo: Whatever)
|
51
24
|
# end
|
52
25
|
# end
|
53
|
-
|
54
|
-
def register_middleware(autoload_path = nil, mapping = nil)
|
55
|
-
if mapping.nil?
|
56
|
-
mapping = autoload_path
|
57
|
-
autoload_path = nil
|
58
|
-
end
|
26
|
+
def register_middleware(**mappings)
|
59
27
|
middleware_mutex do
|
60
|
-
|
61
|
-
(@registered_middleware ||= {}).update(mapping)
|
28
|
+
registered_middleware.update(mappings)
|
62
29
|
end
|
63
30
|
end
|
64
31
|
|
@@ -66,7 +33,7 @@ module Faraday
|
|
66
33
|
#
|
67
34
|
# @param key [Symbol] key for the registered middleware.
|
68
35
|
def unregister_middleware(key)
|
69
|
-
|
36
|
+
registered_middleware.delete(key)
|
70
37
|
end
|
71
38
|
|
72
39
|
# Lookup middleware class with a registered Symbol shortcut.
|
@@ -78,30 +45,27 @@ module Faraday
|
|
78
45
|
# @example
|
79
46
|
#
|
80
47
|
# module Faraday
|
81
|
-
# class Whatever
|
82
|
-
# register_middleware
|
48
|
+
# class Whatever < Middleware
|
49
|
+
# register_middleware(foo: Whatever)
|
83
50
|
# end
|
84
51
|
# end
|
85
52
|
#
|
86
|
-
# Faraday::
|
87
|
-
# # => Faraday::Whatever
|
88
|
-
#
|
53
|
+
# Faraday::Middleware.lookup_middleware(:foo)
|
54
|
+
# # => Faraday::Whatever
|
89
55
|
def lookup_middleware(key)
|
90
56
|
load_middleware(key) ||
|
91
57
|
raise(Faraday::Error, "#{key.inspect} is not registered on #{self}")
|
92
58
|
end
|
93
59
|
|
60
|
+
private
|
61
|
+
|
94
62
|
def middleware_mutex(&block)
|
95
63
|
@middleware_mutex ||= Monitor.new
|
96
64
|
@middleware_mutex.synchronize(&block)
|
97
65
|
end
|
98
66
|
|
99
|
-
def fetch_middleware(key)
|
100
|
-
defined?(@registered_middleware) && @registered_middleware[key]
|
101
|
-
end
|
102
|
-
|
103
67
|
def load_middleware(key)
|
104
|
-
value =
|
68
|
+
value = registered_middleware[key]
|
105
69
|
case value
|
106
70
|
when Module
|
107
71
|
value
|
@@ -113,16 +77,6 @@ module Faraday
|
|
113
77
|
middleware_mutex do
|
114
78
|
@registered_middleware[key] = value.call
|
115
79
|
end
|
116
|
-
when Array
|
117
|
-
middleware_mutex do
|
118
|
-
const, path = value
|
119
|
-
if (root = @middleware_autoload_path)
|
120
|
-
path = "#{root}/#{path}"
|
121
|
-
end
|
122
|
-
require(path)
|
123
|
-
@registered_middleware[key] = const
|
124
|
-
end
|
125
|
-
load_middleware(key)
|
126
80
|
end
|
127
81
|
end
|
128
82
|
end
|