faraday 2.7.0 → 2.13.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1 -1
- data/LICENSE.md +1 -1
- data/README.md +29 -17
- data/Rakefile +6 -1
- data/lib/faraday/adapter/test.rb +20 -7
- data/lib/faraday/adapter.rb +2 -3
- data/lib/faraday/connection.rb +35 -32
- data/lib/faraday/encoders/nested_params_encoder.rb +1 -1
- data/lib/faraday/error.rb +59 -7
- data/lib/faraday/logging/formatter.rb +18 -20
- data/lib/faraday/middleware.rb +40 -1
- data/lib/faraday/options/connection_options.rb +7 -6
- data/lib/faraday/options/env.rb +68 -63
- data/lib/faraday/options/proxy_options.rb +11 -5
- data/lib/faraday/options/request_options.rb +7 -6
- data/lib/faraday/options/ssl_options.rb +57 -50
- data/lib/faraday/options.rb +4 -3
- data/lib/faraday/rack_builder.rb +21 -25
- data/lib/faraday/request/instrumentation.rb +3 -1
- data/lib/faraday/request/json.rb +18 -3
- data/lib/faraday/request.rb +10 -7
- data/lib/faraday/response/json.rb +21 -1
- data/lib/faraday/response/logger.rb +7 -5
- data/lib/faraday/response/raise_error.rb +36 -17
- data/lib/faraday/response.rb +2 -1
- data/lib/faraday/utils/headers.rb +8 -2
- data/lib/faraday/utils.rb +3 -4
- data/lib/faraday/version.rb +1 -1
- data/lib/faraday.rb +2 -1
- data/spec/faraday/adapter/test_spec.rb +29 -0
- data/spec/faraday/connection_spec.rb +17 -2
- data/spec/faraday/error_spec.rb +122 -7
- data/spec/faraday/middleware_spec.rb +143 -0
- data/spec/faraday/options/options_spec.rb +1 -1
- data/spec/faraday/options/proxy_options_spec.rb +35 -0
- data/spec/faraday/params_encoders/nested_spec.rb +2 -1
- data/spec/faraday/request/json_spec.rb +88 -0
- data/spec/faraday/response/json_spec.rb +89 -0
- data/spec/faraday/response/logger_spec.rb +50 -5
- data/spec/faraday/response/raise_error_spec.rb +112 -9
- data/spec/faraday/response_spec.rb +3 -1
- data/spec/faraday/utils/headers_spec.rb +9 -0
- data/spec/faraday/utils_spec.rb +3 -1
- data/spec/faraday_spec.rb +10 -4
- data/spec/spec_helper.rb +6 -5
- data/spec/support/faraday_middleware_subclasses.rb +18 -0
- metadata +26 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 12dedb476a26ae00e5f902e4e10f5327a790290d2d7647711aac09e8661af959
|
4
|
+
data.tar.gz: f43c7bb1127b0a57bb7aa0727a096e0b66cfeead93445631dacf151c354efbdb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b3cb808ea984cc306ad71fc502bf79541d5e79fb9ca066784e0674dc71a2dc22ac20b6968065cceaa3fe5ccb909124aeef9513a37bf83bbcb4a63e116dbd6afe
|
7
|
+
data.tar.gz: 1540d3fe594b1d0a025caede980b99419de50d4ea148b53bf5cf7a3082307982c0917fd739621805252f8016e427ffdbfba59da5a679b529380adf0100cf10ef
|
data/CHANGELOG.md
CHANGED
@@ -517,7 +517,7 @@ Breaking changes:
|
|
517
517
|
- Drop support for Ruby 1.8
|
518
518
|
|
519
519
|
Features:
|
520
|
-
- Include wrapped exception/
|
520
|
+
- Include wrapped exception/response in ClientErrors
|
521
521
|
- Add `response.reason_phrase`
|
522
522
|
- Provide option to selectively skip logging request/response headers
|
523
523
|
- Add regex support for pattern matching in `test` adapter
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -1,26 +1,41 @@
|
|
1
|
-
# [][website]
|
2
2
|
|
3
3
|
[](https://rubygems.org/gems/faraday)
|
4
4
|
[](https://github.com/lostisland/faraday/actions?query=workflow%3ACI)
|
5
5
|
[](https://github.com/lostisland/faraday/discussions)
|
6
6
|
|
7
|
-
|
8
7
|
Faraday is an HTTP client library abstraction layer that provides a common interface over many
|
9
8
|
adapters (such as Net::HTTP) and embraces the concept of Rack middleware when processing the request/response cycle.
|
10
|
-
|
11
|
-
|
9
|
+
Take a look at [Awesome Faraday][awesome] for a list of available adapters and middleware.
|
10
|
+
|
11
|
+
## Why use Faraday?
|
12
|
+
|
13
|
+
Faraday gives you the power of Rack middleware for manipulating HTTP requests and responses,
|
14
|
+
making it easier to build sophisticated API clients or web service libraries that abstract away
|
15
|
+
the details of how HTTP requests are made.
|
16
|
+
|
17
|
+
Faraday comes with a lot of features out of the box, such as:
|
18
|
+
* Support for multiple adapters (Net::HTTP, Typhoeus, Patron, Excon, HTTPClient, and more)
|
19
|
+
* Persistent connections (keep-alive)
|
20
|
+
* Parallel requests
|
21
|
+
* Automatic response parsing (JSON, XML, YAML)
|
22
|
+
* Customization of the request/response cycle with middleware
|
23
|
+
* Support for streaming responses
|
24
|
+
* Support for uploading files
|
25
|
+
* And much more!
|
12
26
|
|
13
27
|
## Getting Started
|
14
28
|
|
15
29
|
The best starting point is the [Faraday Website][website], with its introduction and explanation.
|
16
|
-
|
30
|
+
|
31
|
+
Need more details? See the [Faraday API Documentation][apidoc] to see how it works internally, or take a look at [Advanced techniques for calling HTTP APIs in Ruby](https://mattbrictson.com/blog/advanced-http-techniques-in-ruby) blog post from [@mattbrictson](https://github.com/mattbrictson) 🚀
|
17
32
|
|
18
33
|
## Supported Ruby versions
|
19
34
|
|
20
35
|
This library aims to support and is [tested against][actions] the currently officially supported Ruby
|
21
36
|
implementations. This means that, even without a major release, we could add or drop support for Ruby versions,
|
22
37
|
following their [EOL](https://endoflife.date/ruby).
|
23
|
-
Currently that means we support Ruby
|
38
|
+
Currently that means we support Ruby 3.0+
|
24
39
|
|
25
40
|
If something doesn't work on one of these Ruby versions, it's a bug.
|
26
41
|
|
@@ -42,14 +57,11 @@ Open the issues page and check for the `help wanted` label!
|
|
42
57
|
But before you start coding, please read our [Contributing Guide][contributing]
|
43
58
|
|
44
59
|
## Copyright
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
[
|
49
|
-
[
|
50
|
-
[contributing]: https://github.com/lostisland/faraday/blob/
|
51
|
-
[apidoc]:
|
52
|
-
[actions]:
|
53
|
-
[jruby]: http://jruby.org/
|
54
|
-
[rubinius]: http://rubini.us/
|
55
|
-
[license]: LICENSE.md
|
60
|
+
|
61
|
+
© 2009 - 2023, the Faraday Team. Website and branding design by [Elena Lo Piccolo](https://elelopic.design).
|
62
|
+
|
63
|
+
[awesome]: https://github.com/lostisland/awesome-faraday/#adapters
|
64
|
+
[website]: https://lostisland.github.io/faraday
|
65
|
+
[contributing]: https://github.com/lostisland/faraday/blob/main/.github/CONTRIBUTING.md
|
66
|
+
[apidoc]: https://www.rubydoc.info/github/lostisland/faraday
|
67
|
+
[actions]: https://github.com/lostisland/faraday/actions
|
data/Rakefile
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'rspec/core/rake_task'
|
4
|
+
require 'bundler'
|
4
5
|
|
5
|
-
|
6
|
+
Bundler::GemHelper.install_tasks
|
7
|
+
|
8
|
+
RSpec::Core::RakeTask.new(:spec) do |task|
|
9
|
+
task.ruby_opts = %w[-W]
|
10
|
+
end
|
6
11
|
|
7
12
|
task default: :spec
|
data/lib/faraday/adapter/test.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'timeout'
|
4
|
+
|
3
5
|
module Faraday
|
4
6
|
class Adapter
|
5
7
|
# @example
|
@@ -144,7 +146,7 @@ module Faraday
|
|
144
146
|
# which means that all of a path, parameters, and headers must be the same as an actual request.
|
145
147
|
def strict_mode=(value)
|
146
148
|
@strict_mode = value
|
147
|
-
@stack.
|
149
|
+
@stack.each_value do |stubs|
|
148
150
|
stubs.each do |stub|
|
149
151
|
stub.strict_mode = value
|
150
152
|
end
|
@@ -182,7 +184,7 @@ module Faraday
|
|
182
184
|
end
|
183
185
|
|
184
186
|
# Stub request
|
185
|
-
|
187
|
+
Stub = Struct.new(:host, :path, :query, :headers, :body, :strict_mode, :block) do
|
186
188
|
# @param env [Faraday::Env]
|
187
189
|
def matches?(env)
|
188
190
|
request_host = env[:url].host
|
@@ -238,7 +240,7 @@ module Faraday
|
|
238
240
|
end
|
239
241
|
|
240
242
|
def body_match?(request_body)
|
241
|
-
return true if body.to_s.
|
243
|
+
return true if body.to_s.empty?
|
242
244
|
|
243
245
|
case body
|
244
246
|
when Proc
|
@@ -273,15 +275,26 @@ module Faraday
|
|
273
275
|
|
274
276
|
unless stub
|
275
277
|
raise Stubs::NotFound, "no stubbed request for #{env[:method]} " \
|
276
|
-
"#{env[:url]} #{env[:body]}"
|
278
|
+
"#{env[:url]} #{env[:body]} #{env[:headers]}"
|
277
279
|
end
|
278
280
|
|
279
281
|
block_arity = stub.block.arity
|
282
|
+
params = if block_arity >= 0
|
283
|
+
[env, meta].take(block_arity)
|
284
|
+
else
|
285
|
+
[env, meta]
|
286
|
+
end
|
287
|
+
|
288
|
+
timeout = request_timeout(:open, env[:request])
|
289
|
+
timeout ||= request_timeout(:read, env[:request])
|
290
|
+
|
280
291
|
status, headers, body =
|
281
|
-
if
|
282
|
-
|
292
|
+
if timeout
|
293
|
+
::Timeout.timeout(timeout, Faraday::TimeoutError) do
|
294
|
+
stub.block.call(*params)
|
295
|
+
end
|
283
296
|
else
|
284
|
-
stub.block.call(
|
297
|
+
stub.block.call(*params)
|
285
298
|
end
|
286
299
|
|
287
300
|
# We need to explicitly pass `reason_phrase = nil` here to avoid keyword args conflicts.
|
data/lib/faraday/adapter.rb
CHANGED
@@ -26,7 +26,7 @@ module Faraday
|
|
26
26
|
self.supports_parallel = false
|
27
27
|
|
28
28
|
def initialize(_app = nil, opts = {}, &block)
|
29
|
-
@app =
|
29
|
+
@app = lambda(&:response)
|
30
30
|
@connection_options = opts
|
31
31
|
@config_block = block
|
32
32
|
end
|
@@ -78,8 +78,7 @@ module Faraday
|
|
78
78
|
# @param type [Symbol] Describes which timeout setting to get: :read,
|
79
79
|
# :write, or :open.
|
80
80
|
# @param options [Hash] Hash containing Symbol keys like :timeout,
|
81
|
-
# :read_timeout, :write_timeout, :open_timeout
|
82
|
-
# :timeout
|
81
|
+
# :read_timeout, :write_timeout, or :open_timeout
|
83
82
|
#
|
84
83
|
# @return [Integer, nil] Timeout duration in seconds, or nil if no timeout
|
85
84
|
# has been set.
|
data/lib/faraday/connection.rb
CHANGED
@@ -15,7 +15,7 @@ module Faraday
|
|
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
|
+
USER_AGENT = "Faraday v#{VERSION}".freeze
|
19
19
|
|
20
20
|
# @return [Hash] URI query unencoded key/value pairs.
|
21
21
|
attr_reader :params
|
@@ -220,7 +220,7 @@ module Faraday
|
|
220
220
|
# @yield [Faraday::Request] for further request customizations
|
221
221
|
# @return [Faraday::Response]
|
222
222
|
def options(*args)
|
223
|
-
return @options if args.
|
223
|
+
return @options if args.empty?
|
224
224
|
|
225
225
|
url, params, headers = *args
|
226
226
|
run_request(:options, url, nil, headers) do |request|
|
@@ -261,14 +261,13 @@ module Faraday
|
|
261
261
|
# @param headers [Hash, nil] unencoded HTTP header key/value pairs.
|
262
262
|
#
|
263
263
|
# @example
|
264
|
-
#
|
265
|
-
# conn.post '/items', data, content_type: 'application/json'
|
264
|
+
# conn.put '/products/123', data, content_type: 'application/json'
|
266
265
|
#
|
267
|
-
# #
|
268
|
-
# conn.
|
269
|
-
# req.headers[
|
270
|
-
# req.
|
271
|
-
# 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'
|
272
271
|
# end
|
273
272
|
#
|
274
273
|
# @yield [Faraday::Request] for further request customizations
|
@@ -315,15 +314,23 @@ module Faraday
|
|
315
314
|
#
|
316
315
|
# @yield a block to execute multiple requests.
|
317
316
|
# @return [void]
|
318
|
-
def in_parallel(manager = nil)
|
317
|
+
def in_parallel(manager = nil, &block)
|
319
318
|
@parallel_manager = manager || default_parallel_manager do
|
320
319
|
warn 'Warning: `in_parallel` called but no parallel-capable adapter ' \
|
321
320
|
'on Faraday stack'
|
322
321
|
warn caller[2, 10].join("\n")
|
323
322
|
nil
|
324
323
|
end
|
325
|
-
yield
|
326
|
-
|
324
|
+
return yield unless @parallel_manager
|
325
|
+
|
326
|
+
if @parallel_manager.respond_to?(:execute)
|
327
|
+
# Execute is the new method that is responsible for executing the block.
|
328
|
+
@parallel_manager.execute(&block)
|
329
|
+
else
|
330
|
+
# TODO: Old behaviour, deprecate and remove in 3.0
|
331
|
+
yield
|
332
|
+
@parallel_manager.run
|
333
|
+
end
|
327
334
|
ensure
|
328
335
|
@parallel_manager = nil
|
329
336
|
end
|
@@ -424,8 +431,8 @@ module Faraday
|
|
424
431
|
#
|
425
432
|
# @param method [Symbol] HTTP method.
|
426
433
|
# @param url [String, URI, nil] String or URI to access.
|
427
|
-
# @param body [String, nil] The request body that will eventually be converted to
|
428
|
-
# a string.
|
434
|
+
# @param body [String, Hash, Array, nil] The request body that will eventually be converted to
|
435
|
+
# a string; middlewares can be used to support more complex types.
|
429
436
|
# @param headers [Hash, nil] unencoded HTTP header key/value pairs.
|
430
437
|
#
|
431
438
|
# @return [Faraday::Response]
|
@@ -471,10 +478,11 @@ module Faraday
|
|
471
478
|
def build_exclusive_url(url = nil, params = nil, params_encoder = nil)
|
472
479
|
url = nil if url.respond_to?(:empty?) && url.empty?
|
473
480
|
base = url_prefix.dup
|
474
|
-
if url && base.path
|
481
|
+
if url && !base.path.end_with?('/')
|
475
482
|
base.path = "#{base.path}/" # ensure trailing slash
|
476
483
|
end
|
477
|
-
|
484
|
+
# Ensure relative url will be parsed correctly (such as `service:search` )
|
485
|
+
url = "./#{url}" if url.respond_to?(:start_with?) && !url.start_with?('http://', 'https://', '/', './', '../')
|
478
486
|
uri = url ? base + url : base
|
479
487
|
if params
|
480
488
|
uri.query = params.to_query(params_encoder || options.params_encoder)
|
@@ -515,22 +523,17 @@ module Faraday
|
|
515
523
|
return if Faraday.ignore_env_proxy
|
516
524
|
|
517
525
|
uri = nil
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
when nil
|
530
|
-
uri = find_default_proxy
|
531
|
-
end
|
532
|
-
else
|
533
|
-
warn 'no_proxy is unsupported' if ENV['no_proxy'] || ENV['NO_PROXY']
|
526
|
+
case url
|
527
|
+
when String
|
528
|
+
uri = Utils.URI(url)
|
529
|
+
uri = if uri.host.nil?
|
530
|
+
find_default_proxy
|
531
|
+
else
|
532
|
+
URI.parse("#{uri.scheme}://#{uri.host}").find_proxy
|
533
|
+
end
|
534
|
+
when URI
|
535
|
+
uri = url.find_proxy
|
536
|
+
when nil
|
534
537
|
uri = find_default_proxy
|
535
538
|
end
|
536
539
|
ProxyOptions.from(uri) if uri
|
data/lib/faraday/error.rb
CHANGED
@@ -29,15 +29,21 @@ module Faraday
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def response_status
|
32
|
-
|
32
|
+
return unless @response
|
33
|
+
|
34
|
+
@response.is_a?(Faraday::Response) ? @response.status : @response[:status]
|
33
35
|
end
|
34
36
|
|
35
37
|
def response_headers
|
36
|
-
|
38
|
+
return unless @response
|
39
|
+
|
40
|
+
@response.is_a?(Faraday::Response) ? @response.headers : @response[:headers]
|
37
41
|
end
|
38
42
|
|
39
43
|
def response_body
|
40
|
-
|
44
|
+
return unless @response
|
45
|
+
|
46
|
+
@response.is_a?(Faraday::Response) ? @response.body : @response[:body]
|
41
47
|
end
|
42
48
|
|
43
49
|
protected
|
@@ -73,12 +79,46 @@ module Faraday
|
|
73
79
|
|
74
80
|
# Pulls out potential parent exception and response hash.
|
75
81
|
def exc_msg_and_response(exc, response = nil)
|
76
|
-
|
82
|
+
case exc
|
83
|
+
when Exception
|
84
|
+
[exc, exc.message, response]
|
85
|
+
when Hash
|
86
|
+
[nil, build_error_message_from_hash(exc), exc]
|
87
|
+
when Faraday::Env
|
88
|
+
[nil, build_error_message_from_env(exc), exc]
|
89
|
+
else
|
90
|
+
[nil, exc.to_s, response]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def build_error_message_from_hash(hash)
|
97
|
+
# Be defensive with external Hash objects - they might be missing keys
|
98
|
+
status = hash.fetch(:status, nil)
|
99
|
+
request = hash.fetch(:request, nil)
|
100
|
+
|
101
|
+
return fallback_error_message(status) if request.nil?
|
102
|
+
|
103
|
+
method = request.fetch(:method, nil)
|
104
|
+
url = request.fetch(:url, nil)
|
105
|
+
build_status_error_message(status, method, url)
|
106
|
+
end
|
77
107
|
|
78
|
-
|
79
|
-
|
108
|
+
def build_error_message_from_env(env)
|
109
|
+
# Faraday::Env is internal - we can make reasonable assumptions about its structure
|
110
|
+
build_status_error_message(env.status, env.method, env.url)
|
111
|
+
end
|
80
112
|
|
81
|
-
|
113
|
+
def build_status_error_message(status, method, url)
|
114
|
+
method_str = method ? method.to_s.upcase : ''
|
115
|
+
url_str = url ? url.to_s : ''
|
116
|
+
"the server responded with status #{status} for #{method_str} #{url_str}"
|
117
|
+
end
|
118
|
+
|
119
|
+
def fallback_error_message(status)
|
120
|
+
"the server responded with status #{status} - method and url are not available " \
|
121
|
+
'due to include_request: false on Faraday::Response::RaiseError middleware'
|
82
122
|
end
|
83
123
|
end
|
84
124
|
|
@@ -106,6 +146,10 @@ module Faraday
|
|
106
146
|
class ProxyAuthError < ClientError
|
107
147
|
end
|
108
148
|
|
149
|
+
# Raised by Faraday::Response::RaiseError in case of a 408 response.
|
150
|
+
class RequestTimeoutError < ClientError
|
151
|
+
end
|
152
|
+
|
109
153
|
# Raised by Faraday::Response::RaiseError in case of a 409 response.
|
110
154
|
class ConflictError < ClientError
|
111
155
|
end
|
@@ -114,6 +158,10 @@ module Faraday
|
|
114
158
|
class UnprocessableEntityError < ClientError
|
115
159
|
end
|
116
160
|
|
161
|
+
# Raised by Faraday::Response::RaiseError in case of a 429 response.
|
162
|
+
class TooManyRequestsError < ClientError
|
163
|
+
end
|
164
|
+
|
117
165
|
# Faraday server error class. Represents 5xx status responses.
|
118
166
|
class ServerError < Error
|
119
167
|
end
|
@@ -144,4 +192,8 @@ module Faraday
|
|
144
192
|
# Raised by middlewares that parse the response, like the JSON response middleware.
|
145
193
|
class ParsingError < Error
|
146
194
|
end
|
195
|
+
|
196
|
+
# Raised by Faraday::Middleware and subclasses when invalid default_options are used
|
197
|
+
class InitializationError < Error
|
198
|
+
end
|
147
199
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'pp' # This require is necessary for Hash#pretty_inspect to work, do not remove it, people rely on it.
|
4
|
+
|
3
5
|
module Faraday
|
4
6
|
module Logging
|
5
7
|
# Serves as an integration point to customize logging
|
@@ -11,40 +13,40 @@ module Faraday
|
|
11
13
|
|
12
14
|
def initialize(logger:, options:)
|
13
15
|
@logger = logger
|
14
|
-
@filter = []
|
15
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 = []
|
16
21
|
end
|
17
22
|
|
18
23
|
def_delegators :@logger, :debug, :info, :warn, :error, :fatal
|
19
24
|
|
20
25
|
def request(env)
|
21
|
-
|
22
|
-
"#{env.method.upcase} #{apply_filters(env.url.to_s)}"
|
26
|
+
public_send(log_level) do
|
27
|
+
"request: #{env.method.upcase} #{apply_filters(env.url.to_s)}"
|
23
28
|
end
|
24
|
-
public_send(log_level, 'request', &request_log)
|
25
29
|
|
26
30
|
log_headers('request', env.request_headers) if log_headers?(:request)
|
27
31
|
log_body('request', env[:body]) if env[:body] && log_body?(:request)
|
28
32
|
end
|
29
33
|
|
30
34
|
def response(env)
|
31
|
-
|
32
|
-
public_send(log_level, 'response', &status)
|
35
|
+
public_send(log_level) { "response: Status #{env.status}" }
|
33
36
|
|
34
37
|
log_headers('response', env.response_headers) if log_headers?(:response)
|
35
38
|
log_body('response', env[:body]) if env[:body] && log_body?(:response)
|
36
39
|
end
|
37
40
|
|
38
|
-
def
|
41
|
+
def exception(exc)
|
39
42
|
return unless log_errors?
|
40
43
|
|
41
|
-
|
42
|
-
public_send(log_level, 'error', &error_log)
|
44
|
+
public_send(log_level) { "error: #{exc.full_message}" }
|
43
45
|
|
44
|
-
log_headers('error',
|
45
|
-
return unless
|
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)
|
46
48
|
|
47
|
-
log_body('error',
|
49
|
+
log_body('error', exc.response_body)
|
48
50
|
end
|
49
51
|
|
50
52
|
def filter(filter_word, filter_replacement)
|
@@ -54,6 +56,8 @@ module Faraday
|
|
54
56
|
private
|
55
57
|
|
56
58
|
def dump_headers(headers)
|
59
|
+
return if headers.nil?
|
60
|
+
|
57
61
|
headers.map { |k, v| "#{k}: #{v.inspect}" }.join("\n")
|
58
62
|
end
|
59
63
|
|
@@ -99,21 +103,15 @@ module Faraday
|
|
99
103
|
end
|
100
104
|
|
101
105
|
def log_level
|
102
|
-
unless %i[debug info warn error fatal].include?(@options[:log_level])
|
103
|
-
return :info
|
104
|
-
end
|
105
|
-
|
106
106
|
@options[:log_level]
|
107
107
|
end
|
108
108
|
|
109
109
|
def log_headers(type, headers)
|
110
|
-
|
111
|
-
public_send(log_level, type, &headers_log)
|
110
|
+
public_send(log_level) { "#{type}: #{apply_filters(dump_headers(headers))}" }
|
112
111
|
end
|
113
112
|
|
114
113
|
def log_body(type, body)
|
115
|
-
|
116
|
-
public_send(log_level, type, &body_log)
|
114
|
+
public_send(log_level) { "#{type}: #{apply_filters(dump_body(body))}" }
|
117
115
|
end
|
118
116
|
end
|
119
117
|
end
|
data/lib/faraday/middleware.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'monitor'
|
4
|
+
|
3
5
|
module Faraday
|
4
6
|
# Middleware is the basic base class of any Faraday middleware.
|
5
7
|
class Middleware
|
@@ -7,9 +9,46 @@ module Faraday
|
|
7
9
|
|
8
10
|
attr_reader :app, :options
|
9
11
|
|
12
|
+
DEFAULT_OPTIONS = {}.freeze
|
13
|
+
LOCK = Mutex.new
|
14
|
+
|
10
15
|
def initialize(app = nil, options = {})
|
11
16
|
@app = app
|
12
|
-
@options = options
|
17
|
+
@options = self.class.default_options.merge(options)
|
18
|
+
end
|
19
|
+
|
20
|
+
class << self
|
21
|
+
# Faraday::Middleware::default_options= allows user to set default options at the Faraday::Middleware
|
22
|
+
# class level.
|
23
|
+
#
|
24
|
+
# @example Set the Faraday::Response::RaiseError option, `include_request` to `false`
|
25
|
+
# my_app/config/initializers/my_faraday_middleware.rb
|
26
|
+
#
|
27
|
+
# Faraday::Response::RaiseError.default_options = { include_request: false }
|
28
|
+
#
|
29
|
+
def default_options=(options = {})
|
30
|
+
validate_default_options(options)
|
31
|
+
LOCK.synchronize do
|
32
|
+
@default_options = default_options.merge(options)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# default_options attr_reader that initializes class instance variable
|
37
|
+
# with the values of any Faraday::Middleware defaults, and merges with
|
38
|
+
# subclass defaults
|
39
|
+
def default_options
|
40
|
+
@default_options ||= DEFAULT_OPTIONS.merge(self::DEFAULT_OPTIONS)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def validate_default_options(options)
|
46
|
+
invalid_keys = options.keys.reject { |opt| self::DEFAULT_OPTIONS.key?(opt) }
|
47
|
+
return unless invalid_keys.any?
|
48
|
+
|
49
|
+
raise(Faraday::InitializationError,
|
50
|
+
"Invalid options provided. Keys not found in #{self}::DEFAULT_OPTIONS: #{invalid_keys.join(', ')}")
|
51
|
+
end
|
13
52
|
end
|
14
53
|
|
15
54
|
def call(env)
|
@@ -1,12 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Faraday
|
4
|
-
#
|
5
|
-
#
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
# @!parse
|
5
|
+
# # ConnectionOptions contains the configurable properties for a Faraday
|
6
|
+
# # connection object.
|
7
|
+
# class ConnectionOptions < Options; end
|
8
|
+
ConnectionOptions = Options.new(:request, :proxy, :ssl, :builder, :url,
|
9
|
+
:parallel_manager, :params, :headers,
|
10
|
+
:builder_class) do
|
10
11
|
options request: RequestOptions, ssl: SSLOptions
|
11
12
|
|
12
13
|
memoized(:request) { self.class.options_for(:request).new }
|