faraday 1.1.0 → 2.9.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/CHANGELOG.md +299 -1
- data/LICENSE.md +1 -1
- data/README.md +34 -21
- data/Rakefile +3 -1
- 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 -20
- data/lib/faraday/connection.rb +70 -129
- data/lib/faraday/encoders/nested_params_encoder.rb +14 -7
- data/lib/faraday/error.rb +29 -8
- data/lib/faraday/logging/formatter.rb +28 -15
- data/lib/faraday/methods.rb +6 -0
- data/lib/faraday/middleware.rb +17 -5
- data/lib/faraday/middleware_registry.rb +17 -63
- data/lib/faraday/options/connection_options.rb +7 -6
- data/lib/faraday/options/env.rb +85 -62
- data/lib/faraday/options/proxy_options.rb +11 -3
- data/lib/faraday/options/request_options.rb +7 -6
- data/lib/faraday/options/ssl_options.rb +56 -45
- data/lib/faraday/options.rb +7 -6
- data/lib/faraday/rack_builder.rb +23 -21
- data/lib/faraday/request/authorization.rb +37 -38
- data/lib/faraday/request/instrumentation.rb +5 -1
- data/lib/faraday/request/json.rb +70 -0
- data/lib/faraday/request/url_encoded.rb +5 -1
- data/lib/faraday/request.rb +20 -37
- data/lib/faraday/response/json.rb +73 -0
- data/lib/faraday/response/logger.rb +8 -4
- data/lib/faraday/response/raise_error.rb +33 -6
- data/lib/faraday/response.rb +10 -26
- data/lib/faraday/utils/headers.rb +7 -2
- data/lib/faraday/utils.rb +11 -7
- data/lib/faraday/version.rb +5 -0
- data/lib/faraday.rb +49 -58
- data/spec/faraday/adapter/test_spec.rb +182 -0
- data/spec/faraday/connection_spec.rb +207 -90
- data/spec/faraday/error_spec.rb +45 -5
- data/spec/faraday/middleware_registry_spec.rb +31 -0
- data/spec/faraday/middleware_spec.rb +50 -6
- data/spec/faraday/options/env_spec.rb +8 -2
- data/spec/faraday/options/options_spec.rb +1 -1
- data/spec/faraday/options/proxy_options_spec.rb +15 -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 +199 -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 +189 -0
- data/spec/faraday/response/logger_spec.rb +38 -0
- data/spec/faraday/response/raise_error_spec.rb +77 -5
- 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/faraday_spec.rb +8 -4
- data/spec/spec_helper.rb +6 -5
- data/spec/support/fake_safe_buffer.rb +1 -1
- data/spec/support/helper_methods.rb +0 -37
- data/spec/support/shared_examples/adapter.rb +4 -3
- data/spec/support/shared_examples/request_method.rb +58 -29
- metadata +17 -57
- data/lib/faraday/adapter/em_http.rb +0 -286
- 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 -150
- data/lib/faraday/adapter/excon.rb +0 -124
- data/lib/faraday/adapter/httpclient.rb +0 -152
- data/lib/faraday/adapter/net_http.rb +0 -219
- data/lib/faraday/adapter/net_http_persistent.rb +0 -91
- 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 -95
- data/lib/faraday/dependency_loader.rb +0 -39
- 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_persistent_spec.rb +0 -57
- 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}".freeze
|
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,18 +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
|
476
|
+
url = url.to_s.gsub(':', '%3A') if URI.parse(url.to_s).opaque
|
525
477
|
uri = url ? base + url : base
|
526
478
|
if params
|
527
479
|
uri.query = params.to_query(params_encoder || options.params_encoder)
|
528
480
|
end
|
529
|
-
# rubocop:disable Style/SafeNavigation
|
530
481
|
uri.query = nil if uri.query && uri.query.empty?
|
531
|
-
# rubocop:enable Style/SafeNavigation
|
532
482
|
uri
|
533
483
|
end
|
534
484
|
|
@@ -560,37 +510,28 @@ module Faraday
|
|
560
510
|
yield(Utils.unescape(uri.user), Utils.unescape(uri.password))
|
561
511
|
end
|
562
512
|
|
563
|
-
def set_authorization_header(header_type, *args)
|
564
|
-
header = Faraday::Request
|
565
|
-
.lookup_middleware(header_type)
|
566
|
-
.header(*args)
|
567
|
-
|
568
|
-
headers[Faraday::Request::Authorization::KEY] = header
|
569
|
-
end
|
570
|
-
|
571
513
|
def proxy_from_env(url)
|
572
514
|
return if Faraday.ignore_env_proxy
|
573
515
|
|
574
516
|
uri = nil
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
warn 'no_proxy is unsupported' if ENV['no_proxy'] || ENV['NO_PROXY']
|
517
|
+
case url
|
518
|
+
when String
|
519
|
+
uri = Utils.URI(url)
|
520
|
+
uri = if uri.host.nil?
|
521
|
+
find_default_proxy
|
522
|
+
else
|
523
|
+
URI.parse("#{uri.scheme}://#{uri.host}").find_proxy
|
524
|
+
end
|
525
|
+
when URI
|
526
|
+
uri = url.find_proxy
|
527
|
+
when nil
|
587
528
|
uri = find_default_proxy
|
588
529
|
end
|
589
530
|
ProxyOptions.from(uri) if uri
|
590
531
|
end
|
591
532
|
|
592
533
|
def find_default_proxy
|
593
|
-
uri = ENV
|
534
|
+
uri = ENV.fetch('http_proxy', nil)
|
594
535
|
return unless uri && !uri.empty?
|
595
536
|
|
596
537
|
uri = "http://#{uri}" unless uri.match?(/^http/i)
|
@@ -608,7 +549,7 @@ module Faraday
|
|
608
549
|
end
|
609
550
|
|
610
551
|
def support_parallel?(adapter)
|
611
|
-
adapter
|
552
|
+
adapter.respond_to?(:supports_parallel?) && adapter&.supports_parallel?
|
612
553
|
end
|
613
554
|
end
|
614
555
|
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
|
@@ -96,13 +102,13 @@ module Faraday
|
|
96
102
|
|
97
103
|
protected
|
98
104
|
|
99
|
-
SUBKEYS_REGEX = /[^\[\]]+(?:\]?\[\])
|
105
|
+
SUBKEYS_REGEX = /[^\[\]]+(?:\]?\[\])?/
|
100
106
|
|
101
107
|
def decode_pair(key, value, context)
|
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))
|
@@ -28,6 +28,24 @@ module Faraday
|
|
28
28
|
%(#<#{self.class}#{inner}>)
|
29
29
|
end
|
30
30
|
|
31
|
+
def response_status
|
32
|
+
return unless @response
|
33
|
+
|
34
|
+
@response.is_a?(Faraday::Response) ? @response.status : @response[:status]
|
35
|
+
end
|
36
|
+
|
37
|
+
def response_headers
|
38
|
+
return unless @response
|
39
|
+
|
40
|
+
@response.is_a?(Faraday::Response) ? @response.headers : @response[:headers]
|
41
|
+
end
|
42
|
+
|
43
|
+
def response_body
|
44
|
+
return unless @response
|
45
|
+
|
46
|
+
@response.is_a?(Faraday::Response) ? @response.body : @response[:body]
|
47
|
+
end
|
48
|
+
|
31
49
|
protected
|
32
50
|
|
33
51
|
# Pulls out potential parent exception and response hash, storing them in
|
@@ -40,6 +58,7 @@ module Faraday
|
|
40
58
|
# :body - Optional string HTTP response body.
|
41
59
|
# :request - Hash
|
42
60
|
# :method - Symbol with the request HTTP method.
|
61
|
+
# :url - URI object with the url requested.
|
43
62
|
# :url_path - String with the url path requested.
|
44
63
|
# :params - String key/value hash of query params
|
45
64
|
# present in the request.
|
@@ -93,6 +112,10 @@ module Faraday
|
|
93
112
|
class ProxyAuthError < ClientError
|
94
113
|
end
|
95
114
|
|
115
|
+
# Raised by Faraday::Response::RaiseError in case of a 408 response.
|
116
|
+
class RequestTimeoutError < ClientError
|
117
|
+
end
|
118
|
+
|
96
119
|
# Raised by Faraday::Response::RaiseError in case of a 409 response.
|
97
120
|
class ConflictError < ClientError
|
98
121
|
end
|
@@ -101,6 +124,10 @@ module Faraday
|
|
101
124
|
class UnprocessableEntityError < ClientError
|
102
125
|
end
|
103
126
|
|
127
|
+
# Raised by Faraday::Response::RaiseError in case of a 429 response.
|
128
|
+
class TooManyRequestsError < ClientError
|
129
|
+
end
|
130
|
+
|
104
131
|
# Faraday server error class. Represents 5xx status responses.
|
105
132
|
class ServerError < Error
|
106
133
|
end
|
@@ -128,13 +155,7 @@ module Faraday
|
|
128
155
|
class SSLError < Error
|
129
156
|
end
|
130
157
|
|
131
|
-
# Raised by
|
158
|
+
# Raised by middlewares that parse the response, like the JSON response middleware.
|
132
159
|
class ParsingError < Error
|
133
160
|
end
|
134
|
-
|
135
|
-
# Exception used to control the Retry middleware.
|
136
|
-
#
|
137
|
-
# @see Faraday::Request::Retry
|
138
|
-
class RetriableResponse < Error
|
139
|
-
end
|
140
161
|
end
|
@@ -1,41 +1,54 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'pp'
|
3
|
+
require 'pp' # This require is necessary for Hash#pretty_inspect to work, do not remove it, people rely on it.
|
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:)
|
14
15
|
@logger = logger
|
15
|
-
@filter = []
|
16
16
|
@options = DEFAULT_OPTIONS.merge(options)
|
17
|
+
unless %i[debug info warn error fatal].include?(@options[:log_level])
|
18
|
+
@options[:log_level] = :info
|
19
|
+
end
|
20
|
+
@filter = []
|
17
21
|
end
|
18
22
|
|
19
23
|
def_delegators :@logger, :debug, :info, :warn, :error, :fatal
|
20
24
|
|
21
25
|
def request(env)
|
22
|
-
|
26
|
+
public_send(log_level, 'request') do
|
23
27
|
"#{env.method.upcase} #{apply_filters(env.url.to_s)}"
|
24
28
|
end
|
25
|
-
public_send(log_level, 'request', &request_log)
|
26
29
|
|
27
30
|
log_headers('request', env.request_headers) if log_headers?(:request)
|
28
31
|
log_body('request', env[:body]) if env[:body] && log_body?(:request)
|
29
32
|
end
|
30
33
|
|
31
34
|
def response(env)
|
32
|
-
|
33
|
-
public_send(log_level, 'response', &status)
|
35
|
+
public_send(log_level, 'response') { "Status #{env.status}" }
|
34
36
|
|
35
37
|
log_headers('response', env.response_headers) if log_headers?(:response)
|
36
38
|
log_body('response', env[:body]) if env[:body] && log_body?(:response)
|
37
39
|
end
|
38
40
|
|
41
|
+
def exception(exc)
|
42
|
+
return unless log_errors?
|
43
|
+
|
44
|
+
public_send(log_level, 'error') { exc.full_message }
|
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
|
@@ -43,6 +56,8 @@ module Faraday
|
|
43
56
|
private
|
44
57
|
|
45
58
|
def dump_headers(headers)
|
59
|
+
return if headers.nil?
|
60
|
+
|
46
61
|
headers.map { |k, v| "#{k}: #{v.inspect}" }.join("\n")
|
47
62
|
end
|
48
63
|
|
@@ -76,6 +91,10 @@ module Faraday
|
|
76
91
|
end
|
77
92
|
end
|
78
93
|
|
94
|
+
def log_errors?
|
95
|
+
@options[:errors]
|
96
|
+
end
|
97
|
+
|
79
98
|
def apply_filters(output)
|
80
99
|
@filter.each do |pattern, replacement|
|
81
100
|
output = output.to_s.gsub(pattern, replacement)
|
@@ -84,21 +103,15 @@ module Faraday
|
|
84
103
|
end
|
85
104
|
|
86
105
|
def log_level
|
87
|
-
unless %i[debug info warn error fatal].include?(@options[:log_level])
|
88
|
-
return :info
|
89
|
-
end
|
90
|
-
|
91
106
|
@options[:log_level]
|
92
107
|
end
|
93
108
|
|
94
109
|
def log_headers(type, headers)
|
95
|
-
|
96
|
-
public_send(log_level, type, &headers_log)
|
110
|
+
public_send(log_level, type) { apply_filters(dump_headers(headers)) }
|
97
111
|
end
|
98
112
|
|
99
113
|
def log_body(type, body)
|
100
|
-
|
101
|
-
public_send(log_level, type, &body_log)
|
114
|
+
public_send(log_level, type) { apply_filters(dump_body(body)) }
|
102
115
|
end
|
103
116
|
end
|
104
117
|
end
|
data/lib/faraday/middleware.rb
CHANGED
@@ -4,17 +4,29 @@ 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
|
9
|
+
|
10
|
+
def initialize(app = nil, options = {})
|
10
11
|
@app = app
|
12
|
+
@options = options
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
on_request(env) if respond_to?(:on_request)
|
17
|
+
app.call(env).on_complete do |environment|
|
18
|
+
on_complete(environment) if respond_to?(:on_complete)
|
19
|
+
end
|
20
|
+
rescue StandardError => e
|
21
|
+
on_error(e) if respond_to?(:on_error)
|
22
|
+
raise
|
11
23
|
end
|
12
24
|
|
13
25
|
def close
|
14
|
-
if
|
15
|
-
|
26
|
+
if app.respond_to?(:close)
|
27
|
+
app.close
|
16
28
|
else
|
17
|
-
warn "#{
|
29
|
+
warn "#{app} does not implement \#close!"
|
18
30
|
end
|
19
31
|
end
|
20
32
|
end
|