better-faraday 1.1.4 → 2.0.1
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/.ruby-version +1 -1
- data/better-faraday.gemspec +2 -2
- data/lib/better-faraday.rb +165 -100
- metadata +7 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c8f236710b44dc72e1efa535f4750f9cc782bce797be1d771da23d7f2ff3ded1
|
|
4
|
+
data.tar.gz: 4f9c6d1453f308abb928b234429f68c26345056c6b1ff8df2efc17dafce73bcf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a3a4bb57f6938d021ebf37e9f854e06b55e4022f2ea983a62de1264085c64807a30d8eeeec72c8913b3dd6229c8777293ab2577b4aabd5cc41dd9e1c0b6d3db4
|
|
7
|
+
data.tar.gz: c0f632bb82dd8eeb84a071d12b1f957a9542494278eaa297e774ca71ef2c1a8a52bad868bec86410b74e9d9beafcb0f823b9eb64b8d4cefc8da840f47befc07f
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.
|
|
1
|
+
2.7.3
|
data/better-faraday.gemspec
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
Gem::Specification.new do |s|
|
|
5
5
|
s.name = "better-faraday"
|
|
6
|
-
s.version = "
|
|
6
|
+
s.version = "2.0.1"
|
|
7
7
|
s.author = "Yaroslav Konoplov"
|
|
8
8
|
s.email = "eahome00@gmail.com"
|
|
9
9
|
s.summary = "Extends Faraday with useful features."
|
|
@@ -13,6 +13,6 @@ Gem::Specification.new do |s|
|
|
|
13
13
|
s.files = `git ls-files -z`.split("\x0")
|
|
14
14
|
s.test_files = `git ls-files -z -- {test,spec,features}/*`.split("\x0")
|
|
15
15
|
s.require_paths = ["lib"]
|
|
16
|
-
s.add_dependency "faraday", ">= 0
|
|
16
|
+
s.add_dependency "faraday", ">= 1.0", "< 3.0"
|
|
17
17
|
s.add_dependency "activesupport", ">= 4.0", "< 7.0"
|
|
18
18
|
end
|
data/lib/better-faraday.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require "json"
|
|
5
|
+
require "net/http"
|
|
5
6
|
require "faraday"
|
|
6
7
|
require "faraday/error"
|
|
7
8
|
require "faraday/options"
|
|
@@ -9,50 +10,83 @@ require "faraday/response"
|
|
|
9
10
|
require "active_support/core_ext/object/deep_dup"
|
|
10
11
|
require "active_support/core_ext/string/filters"
|
|
11
12
|
require "active_support/core_ext/string/inflections"
|
|
13
|
+
require "active_support/core_ext/object/inclusion"
|
|
12
14
|
|
|
13
15
|
Module.new do
|
|
14
|
-
def call(
|
|
15
|
-
|
|
16
|
+
def call(environment)
|
|
17
|
+
environment.instance_variable_set(:@bf_request_sent_at, Time.now.utc)
|
|
16
18
|
super
|
|
17
19
|
end
|
|
18
20
|
|
|
19
|
-
def save_response(
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
def save_response(environment, *)
|
|
22
|
+
environment.instance_variable_set \
|
|
23
|
+
:@bf_response_received_at,
|
|
24
|
+
Time.now.utc
|
|
25
|
+
|
|
26
|
+
body = environment.body
|
|
27
|
+
value = body.respond_to?(:read) ? body.read : body
|
|
28
|
+
value = value.to_s unless String === value
|
|
29
|
+
|
|
30
|
+
environment.instance_variable_set \
|
|
31
|
+
:@bf_request_body,
|
|
32
|
+
value
|
|
33
|
+
|
|
22
34
|
super
|
|
23
35
|
end
|
|
24
|
-
end.tap { |m| Faraday::Adapter.
|
|
36
|
+
end.tap { |m| Faraday::Adapter.prepend(m) }
|
|
25
37
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
38
|
+
Module.new do
|
|
39
|
+
def end_transport(request, response)
|
|
40
|
+
headers = request.to_hash
|
|
41
|
+
headers.keys.each { |k| headers[k] = headers[k].join(", ") }
|
|
42
|
+
response.instance_variable_set :@bf_request_headers, headers
|
|
43
|
+
super
|
|
29
44
|
end
|
|
45
|
+
end.tap { |m| Net::HTTP.prepend(m) }
|
|
30
46
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
47
|
+
Module.new do
|
|
48
|
+
def perform_request(connection, environment)
|
|
49
|
+
super(connection, environment).tap do |response|
|
|
50
|
+
environment.instance_variable_set \
|
|
51
|
+
:@bf_request_headers,
|
|
52
|
+
response.instance_variable_get(:@bf_request_headers)
|
|
36
53
|
end
|
|
37
54
|
end
|
|
55
|
+
end.tap { |m| Faraday::Adapter::NetHttp.prepend(m) }
|
|
56
|
+
|
|
57
|
+
module Faraday
|
|
58
|
+
class Env
|
|
59
|
+
attr_reader :bf_request_headers, :bf_request_body, :bf_request_sent_at, :bf_response_received_at
|
|
60
|
+
end
|
|
38
61
|
|
|
39
62
|
class Response
|
|
40
|
-
def
|
|
41
|
-
|
|
63
|
+
def assert_status!(code_or_range)
|
|
64
|
+
within_range = if Range === code_or_range
|
|
65
|
+
status.in?(code_or_range)
|
|
66
|
+
else
|
|
67
|
+
status == code_or_range
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
return self if within_range
|
|
42
71
|
|
|
43
72
|
klass = if status_4xx?
|
|
44
|
-
"
|
|
73
|
+
"BetterFaraday::HTTP#{status}".safe_constantize || BetterFaraday::HTTP4xx
|
|
74
|
+
elsif status_5xx?
|
|
75
|
+
"BetterFaraday::HTTP#{status}".safe_constantize || BetterFaraday::HTTP5xx
|
|
45
76
|
else
|
|
46
|
-
|
|
77
|
+
BetterFaraday::HTTPError
|
|
47
78
|
end
|
|
48
79
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
80
|
+
raise klass.new(self)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def assert_2xx!
|
|
84
|
+
assert_status!(200..299)
|
|
52
85
|
end
|
|
53
86
|
|
|
54
|
-
|
|
55
|
-
|
|
87
|
+
def assert_200!
|
|
88
|
+
assert_status! 200
|
|
89
|
+
end
|
|
56
90
|
|
|
57
91
|
def status_2xx?
|
|
58
92
|
status >= 200 && status <= 299
|
|
@@ -70,92 +104,95 @@ module Faraday
|
|
|
70
104
|
status >= 500 && status <= 599
|
|
71
105
|
end
|
|
72
106
|
|
|
73
|
-
def
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
107
|
+
def inspect
|
|
108
|
+
@inspection_text ||= begin
|
|
109
|
+
request_headers = bf_protect_data(env.bf_request_headers.dup)
|
|
110
|
+
request_body = env.bf_request_body.yield_self { |body| String === body ? body : body.to_s }
|
|
111
|
+
request_body_bytes_count = env.bf_request_body.bytesize
|
|
112
|
+
response_body = env.body.yield_self { |body| String === body ? body : body.to_s }
|
|
113
|
+
response_body_bytes_count = response_body.bytesize
|
|
114
|
+
|
|
115
|
+
if env.bf_request_headers["content-type"].to_s.match?(/\bapplication\/json\b/i)
|
|
116
|
+
request_json = bf_json_parse(request_body).yield_self do |data|
|
|
117
|
+
bf_json_dump(bf_protect_data(data)) if data
|
|
118
|
+
end
|
|
119
|
+
end
|
|
83
120
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
121
|
+
if env.response_headers
|
|
122
|
+
response_headers = bf_protect_data(env.response_headers.to_hash)
|
|
123
|
+
end
|
|
87
124
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
"",
|
|
92
|
-
"-- Request URL --",
|
|
93
|
-
env.url.to_s,
|
|
94
|
-
"",
|
|
95
|
-
"-- Request method --",
|
|
96
|
-
env.method.to_s.upcase,
|
|
97
|
-
"",
|
|
98
|
-
"-- Request headers --",
|
|
99
|
-
::JSON.generate(request_headers).yield_self { |t| t.truncate(2048, omission: "... (truncated, full length: #{t.length})") },
|
|
100
|
-
"",
|
|
101
|
-
|
|
102
|
-
"-- Request body --",
|
|
103
|
-
if request_json
|
|
104
|
-
::JSON.generate(request_json)
|
|
105
|
-
else
|
|
106
|
-
body = env.request_body.to_s.dup
|
|
107
|
-
if body.encoding.name == "ASCII-8BIT"
|
|
108
|
-
"Binary (#{body.size} bytes)"
|
|
109
|
-
else
|
|
110
|
-
body
|
|
125
|
+
if env.response_headers && env.response_headers["content-type"].to_s.match?(/\bapplication\/json\b/i)
|
|
126
|
+
response_json = bf_json_parse(response_body).yield_self do |data|
|
|
127
|
+
bf_json_dump(bf_protect_data(data)) if data
|
|
111
128
|
end
|
|
112
|
-
end
|
|
113
|
-
"",
|
|
114
|
-
|
|
115
|
-
"-- Request sent at --",
|
|
116
|
-
env.request_sent_at.strftime("%Y-%m-%d %H:%M:%S.%2N") + " UTC",
|
|
117
|
-
"",
|
|
129
|
+
end
|
|
118
130
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
env.
|
|
124
|
-
|
|
125
|
-
|
|
131
|
+
lines = [
|
|
132
|
+
"-- #{status} #{reason_phrase} --".upcase,
|
|
133
|
+
"",
|
|
134
|
+
"-- Request URL --",
|
|
135
|
+
env.url.to_s,
|
|
136
|
+
"",
|
|
137
|
+
"-- Request Method --",
|
|
138
|
+
env.method.to_s.upcase,
|
|
139
|
+
"",
|
|
140
|
+
"-- Request Headers --",
|
|
141
|
+
bf_json_dump(request_headers).truncate(2048, omission: "... (truncated)"),
|
|
142
|
+
"",
|
|
126
143
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
else
|
|
131
|
-
body = env.body.to_s.dup
|
|
132
|
-
if body.encoding.name == "ASCII-8BIT"
|
|
133
|
-
"Binary (#{body.size} bytes)"
|
|
144
|
+
%[-- Request Body (#{request_body_bytes_count} #{"byte".pluralize(request_body_bytes_count)}) --],
|
|
145
|
+
if request_json
|
|
146
|
+
request_json
|
|
134
147
|
else
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
148
|
+
# String#inspect returns \x{XXXX} for the encoding other than Unicode.
|
|
149
|
+
# [1..-2] removed leading and trailing " added by String#inspect.
|
|
150
|
+
# gsub(/\\"/, "\"") unescapes ".
|
|
151
|
+
request_body.inspect.gsub(/\\"/, "\"")[1..-2]
|
|
152
|
+
end.truncate(2048, omission: "... (truncated)"),
|
|
153
|
+
"",
|
|
139
154
|
|
|
140
|
-
|
|
141
|
-
|
|
155
|
+
"-- Request Sent At --",
|
|
156
|
+
env.bf_request_sent_at.strftime("%Y-%m-%d %H:%M:%S.%3N") + " UTC",
|
|
142
157
|
"",
|
|
143
|
-
|
|
144
|
-
|
|
158
|
+
|
|
159
|
+
"-- Response Headers --",
|
|
160
|
+
if response_headers
|
|
161
|
+
bf_json_dump(response_headers)
|
|
162
|
+
else
|
|
163
|
+
env.response_headers.to_s.inspect.gsub(/\\"/, "\"")[1..-2]
|
|
164
|
+
end.truncate(2048, omission: "... (truncated)"),
|
|
145
165
|
"",
|
|
146
|
-
|
|
147
|
-
|
|
166
|
+
|
|
167
|
+
%[-- Response Body (#{response_body_bytes_count} #{"byte".pluralize(response_body_bytes_count)}) --],
|
|
168
|
+
if response_json
|
|
169
|
+
response_json
|
|
170
|
+
else
|
|
171
|
+
response_body.inspect.gsub(/\\"/, "\"")[1..-2]
|
|
172
|
+
end.truncate(2048, omission: "... (truncated)"),
|
|
173
|
+
""
|
|
148
174
|
]
|
|
175
|
+
|
|
176
|
+
if env.bf_response_received_at
|
|
177
|
+
lines.concat [
|
|
178
|
+
"-- Response Received At --",
|
|
179
|
+
env.bf_response_received_at.strftime("%Y-%m-%d %H:%M:%S.%3N") + " UTC",
|
|
180
|
+
"",
|
|
181
|
+
"-- Response Received In --",
|
|
182
|
+
"#{((env.bf_response_received_at.to_f - env.bf_request_sent_at.to_f) * 1000.0).ceil(3)}ms",
|
|
183
|
+
""
|
|
184
|
+
]
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
lines.join("\n").freeze
|
|
149
188
|
end
|
|
150
189
|
|
|
151
|
-
|
|
190
|
+
@inspection_text.dup
|
|
152
191
|
end
|
|
153
192
|
|
|
154
|
-
alias inspect describe
|
|
155
|
-
|
|
156
193
|
private
|
|
157
194
|
|
|
158
|
-
def
|
|
195
|
+
def bf_json_parse(json)
|
|
159
196
|
return nil unless ::String === json
|
|
160
197
|
data = ::JSON.parse(json)
|
|
161
198
|
data if ::Hash === data || ::Array === data
|
|
@@ -163,30 +200,58 @@ module Faraday
|
|
|
163
200
|
nil
|
|
164
201
|
end
|
|
165
202
|
|
|
166
|
-
def
|
|
167
|
-
|
|
203
|
+
def bf_json_dump(data)
|
|
204
|
+
::JSON.generate(data, space: " ", object_nl: " ", array_nl: " ")
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def bf_protect_data(data)
|
|
208
|
+
return data.map(&method(:bf_protect_data)) if ::Array === data
|
|
168
209
|
return data unless ::Hash === data
|
|
210
|
+
|
|
211
|
+
signs = BetterFaraday.sensitive_data_signs
|
|
212
|
+
|
|
169
213
|
data.each_with_object({}) do |(key, value), memo|
|
|
170
|
-
memo[key] = if key.to_s.underscore.tr("_", " ").yield_self { |k|
|
|
214
|
+
memo[key] = if key.to_s.underscore.tr("_", " ").yield_self { |k| signs.any? { |r| k.match?(r) } }
|
|
171
215
|
"SECRET"
|
|
172
216
|
else
|
|
173
|
-
|
|
217
|
+
bf_protect_data(value)
|
|
174
218
|
end
|
|
175
219
|
end
|
|
176
220
|
end
|
|
177
221
|
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
module BetterFaraday
|
|
225
|
+
class HTTPError < Faraday::Error
|
|
226
|
+
def initialize(response)
|
|
227
|
+
super(response.inspect, response)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def inspect
|
|
231
|
+
%[#{self.class}\n\n#{response.inspect}]
|
|
232
|
+
end
|
|
233
|
+
end
|
|
178
234
|
|
|
179
|
-
class HTTP4xx <
|
|
235
|
+
class HTTP4xx < HTTPError; end
|
|
180
236
|
class HTTP400 < HTTP4xx; end
|
|
181
237
|
class HTTP401 < HTTP4xx; end
|
|
182
238
|
class HTTP403 < HTTP4xx; end
|
|
183
239
|
class HTTP404 < HTTP4xx; end
|
|
184
240
|
class HTTP422 < HTTP4xx; end
|
|
185
241
|
class HTTP429 < HTTP4xx; end
|
|
242
|
+
class HTTP5xx < HTTPError; end
|
|
243
|
+
class HTTP500 < HTTP5xx; end
|
|
244
|
+
class HTTP502 < HTTP5xx; end
|
|
245
|
+
class HTTP503 < HTTP5xx; end
|
|
186
246
|
|
|
187
247
|
class << self
|
|
188
|
-
attr_accessor :
|
|
248
|
+
attr_accessor :sensitive_data_signs
|
|
189
249
|
end
|
|
190
250
|
|
|
191
|
-
self.
|
|
251
|
+
self.sensitive_data_signs = [
|
|
252
|
+
/\bpass(?:word|phrase)\b/i,
|
|
253
|
+
/\bauthorization\b/i,
|
|
254
|
+
/\bsecret\b/i,
|
|
255
|
+
/\b(:?access)?token\b/i
|
|
256
|
+
]
|
|
192
257
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: better-faraday
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yaroslav Konoplov
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-05-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
@@ -16,20 +16,20 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '0
|
|
19
|
+
version: '1.0'
|
|
20
20
|
- - "<"
|
|
21
21
|
- !ruby/object:Gem::Version
|
|
22
|
-
version: '
|
|
22
|
+
version: '3.0'
|
|
23
23
|
type: :runtime
|
|
24
24
|
prerelease: false
|
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
26
26
|
requirements:
|
|
27
27
|
- - ">="
|
|
28
28
|
- !ruby/object:Gem::Version
|
|
29
|
-
version: '0
|
|
29
|
+
version: '1.0'
|
|
30
30
|
- - "<"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '
|
|
32
|
+
version: '3.0'
|
|
33
33
|
- !ruby/object:Gem::Dependency
|
|
34
34
|
name: activesupport
|
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -82,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
82
82
|
- !ruby/object:Gem::Version
|
|
83
83
|
version: '0'
|
|
84
84
|
requirements: []
|
|
85
|
-
rubygems_version: 3.1.
|
|
85
|
+
rubygems_version: 3.1.6
|
|
86
86
|
signing_key:
|
|
87
87
|
specification_version: 4
|
|
88
88
|
summary: Extends Faraday with useful features.
|