lhc 9.2.0 → 9.3.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/.rubocop.localch.yml +155 -21
- data/.rubocop.yml +12 -0
- data/docs/interceptors/authentication.md +21 -0
- data/lhc.gemspec +9 -9
- data/lib/lhc/concerns/lhc/basic_methods_concern.rb +1 -1
- data/lib/lhc/config.rb +3 -3
- data/lib/lhc/endpoint.rb +4 -3
- data/lib/lhc/interceptors.rb +1 -1
- data/lib/lhc/interceptors/auth.rb +77 -14
- data/lib/lhc/interceptors/caching.rb +2 -2
- data/lib/lhc/interceptors/logging.rb +2 -2
- data/lib/lhc/request.rb +1 -1
- data/lib/lhc/response/data.rb +1 -1
- data/lib/lhc/version.rb +1 -1
- data/spec/basic_methods/delete_spec.rb +2 -2
- data/spec/basic_methods/get_spec.rb +2 -2
- data/spec/basic_methods/post_spec.rb +2 -2
- data/spec/basic_methods/put_spec.rb +2 -2
- data/spec/endpoint/match_spec.rb +2 -2
- data/spec/endpoint/placeholders_spec.rb +2 -2
- data/spec/error/to_s_spec.rb +3 -3
- data/spec/interceptors/after_response_spec.rb +1 -4
- data/spec/interceptors/auth/reauthentication_configuration_spec.rb +59 -0
- data/spec/interceptors/auth/reauthentication_spec.rb +32 -0
- data/spec/interceptors/caching/methods_spec.rb +2 -4
- data/spec/interceptors/caching/options_spec.rb +4 -5
- data/spec/interceptors/monitoring/main_spec.rb +2 -4
- data/spec/interceptors/zipkin/distributed_tracing_spec.rb +1 -1
- data/spec/request/ignore_errors_spec.rb +1 -0
- data/spec/response/success_spec.rb +2 -2
- data/spec/response/time_spec.rb +1 -1
- data/spec/support/zipkin_mock.rb +2 -4
- metadata +43 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c7d1ebc28ca92627c9828b98adffdf9e57cd41e
|
4
|
+
data.tar.gz: f69dcd78f74648df6cf81189743fce7e9b78e2ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: beb8f74e3901b68de00d2d2c3ebc9874666aee0dac0eaef6d49a16482f1d82a45cf6f47e9aad98ae0ffc60cc5784a7c04d7865acc95a90e68a3e681d31fe52fd
|
7
|
+
data.tar.gz: 1df77507930a88568ef63e9fab8f62ee9a09440b7d8d1b2502f703652d22d7cfe15b423612bc7a11233cd6731bb0c18c64d87809a4bc59e7452e94afae1ad8bb
|
data/.rubocop.localch.yml
CHANGED
@@ -1,22 +1,21 @@
|
|
1
1
|
# This is master rubocop configuration.
|
2
2
|
# DO NOT EDIT THIS FILE - it WILL be overwriten on every config update
|
3
3
|
AllCops:
|
4
|
-
TargetRubyVersion: 2.
|
4
|
+
TargetRubyVersion: 2.3
|
5
5
|
DisplayCopNames: true
|
6
6
|
DisplayStyleGuide: true
|
7
|
-
Include:
|
8
|
-
- '**/Rakefile'
|
9
|
-
- '**/config.ru'
|
10
|
-
- '**/Capfile'
|
11
7
|
Exclude:
|
12
8
|
- 'db/**/*'
|
13
9
|
- 'script/**/*'
|
14
10
|
- 'vendor/bundle/**/*'
|
11
|
+
- 'vendor/assets/**/*'
|
15
12
|
- 'bin/**/*'
|
16
13
|
- 'config/unicorn.rb'
|
17
14
|
- 'config/compass.rb'
|
18
15
|
- 'Rakefile'
|
19
|
-
- '
|
16
|
+
- 'app/controllers/error_trap_controller.rb'
|
17
|
+
- 'app/controllers/hsts_controller.rb'
|
18
|
+
- 'spec/lib/util_spec.rb'
|
20
19
|
|
21
20
|
Rails:
|
22
21
|
Enabled: true
|
@@ -24,10 +23,19 @@ Rails:
|
|
24
23
|
require:
|
25
24
|
- rubocop-rspec
|
26
25
|
|
26
|
+
Bundler/OrderedGems:
|
27
|
+
Enabled: false
|
28
|
+
|
27
29
|
Lint/HandleExceptions:
|
28
30
|
Exclude:
|
29
31
|
- spec/**/*
|
30
32
|
|
33
|
+
Lint/UriEscapeUnescape:
|
34
|
+
Enabled: false
|
35
|
+
|
36
|
+
Style/RescueStandardError:
|
37
|
+
Enabled: false
|
38
|
+
|
31
39
|
Metrics/LineLength:
|
32
40
|
Enabled: false
|
33
41
|
|
@@ -49,6 +57,9 @@ Metrics/ClassLength:
|
|
49
57
|
Metrics/ModuleLength:
|
50
58
|
Enabled: false
|
51
59
|
|
60
|
+
Metrics/BlockLength:
|
61
|
+
Enabled: false
|
62
|
+
|
52
63
|
Metrics/ParameterLists:
|
53
64
|
Enabled: false
|
54
65
|
|
@@ -73,9 +84,39 @@ Performance/RedundantMerge:
|
|
73
84
|
Performance/Casecmp:
|
74
85
|
Enabled: false
|
75
86
|
|
76
|
-
|
87
|
+
Layout/MultilineOperationIndentation:
|
88
|
+
EnforcedStyle: indented
|
89
|
+
|
90
|
+
Layout/DotPosition:
|
91
|
+
EnforcedStyle: leading
|
92
|
+
|
93
|
+
Layout/AlignParameters:
|
94
|
+
Enabled: false
|
95
|
+
|
96
|
+
Layout/EmptyLinesAroundClassBody:
|
97
|
+
Enabled: false
|
98
|
+
|
99
|
+
Layout/IndentArray:
|
100
|
+
EnforcedStyle: consistent
|
101
|
+
|
102
|
+
Layout/MultilineMethodCallIndentation:
|
77
103
|
EnforcedStyle: indented
|
78
104
|
|
105
|
+
Layout/MultilineMethodCallBraceLayout:
|
106
|
+
EnforcedStyle: symmetrical
|
107
|
+
|
108
|
+
Layout/EmptyLinesAroundBlockBody:
|
109
|
+
EnforcedStyle: no_empty_lines
|
110
|
+
|
111
|
+
Layout/IndentHeredoc:
|
112
|
+
Enabled: false
|
113
|
+
|
114
|
+
Layout/MultilineArrayBraceLayout:
|
115
|
+
EnforcedStyle: symmetrical
|
116
|
+
|
117
|
+
Layout/MultilineHashBraceLayout:
|
118
|
+
EnforcedStyle: symmetrical
|
119
|
+
|
79
120
|
Style/StringLiterals:
|
80
121
|
Enabled: false
|
81
122
|
|
@@ -83,21 +124,12 @@ Style/RegexpLiteral:
|
|
83
124
|
Exclude:
|
84
125
|
- spec/**/*
|
85
126
|
|
86
|
-
Style/DotPosition:
|
87
|
-
EnforcedStyle: leading
|
88
|
-
|
89
|
-
Style/AlignParameters:
|
90
|
-
Enabled: false
|
91
|
-
|
92
127
|
Style/NumericLiterals:
|
93
128
|
Enabled: false
|
94
129
|
|
95
130
|
Style/WordArray:
|
96
131
|
Enabled: false
|
97
132
|
|
98
|
-
Style/EmptyLinesAroundClassBody:
|
99
|
-
Enabled: false
|
100
|
-
|
101
133
|
Style/Next:
|
102
134
|
Enabled: false
|
103
135
|
|
@@ -156,7 +188,7 @@ Style/Documentation:
|
|
156
188
|
Style/GuardClause:
|
157
189
|
Enabled: false
|
158
190
|
|
159
|
-
|
191
|
+
Naming/AccessorMethodName:
|
160
192
|
Exclude:
|
161
193
|
- spec/support/pages/**/*
|
162
194
|
|
@@ -169,11 +201,50 @@ Style/MutableConstant:
|
|
169
201
|
Style/ConditionalAssignment:
|
170
202
|
Enabled: false
|
171
203
|
|
172
|
-
Style/
|
173
|
-
|
204
|
+
Style/Lambda:
|
205
|
+
Enabled: false
|
174
206
|
|
175
|
-
Style/
|
176
|
-
|
207
|
+
Style/FrozenStringLiteralComment:
|
208
|
+
Enabled: false
|
209
|
+
|
210
|
+
Style/SymbolArray:
|
211
|
+
Enabled: false
|
212
|
+
|
213
|
+
Style/HashSyntax:
|
214
|
+
EnforcedStyle: ruby19
|
215
|
+
|
216
|
+
Style/FormatStringToken:
|
217
|
+
Enabled: false
|
218
|
+
|
219
|
+
Style/EmptyMethod:
|
220
|
+
EnforcedStyle: expanded
|
221
|
+
|
222
|
+
Style/TernaryParentheses:
|
223
|
+
EnforcedStyle: require_parentheses_when_complex
|
224
|
+
|
225
|
+
Naming/VariableNumber:
|
226
|
+
Enabled: false
|
227
|
+
|
228
|
+
Style/PerlBackrefs:
|
229
|
+
Enabled: false
|
230
|
+
|
231
|
+
Style/RegexpLiteral:
|
232
|
+
AllowInnerSlashes: false
|
233
|
+
|
234
|
+
Style/BlockComments:
|
235
|
+
Enabled: false
|
236
|
+
|
237
|
+
Style/RedundantParentheses:
|
238
|
+
Enabled: false
|
239
|
+
|
240
|
+
Naming/FileName:
|
241
|
+
Exclude:
|
242
|
+
- Gemfile
|
243
|
+
- Brewfile
|
244
|
+
- Guardfile
|
245
|
+
|
246
|
+
Style/NumericPredicate:
|
247
|
+
Enabled: false
|
177
248
|
|
178
249
|
RSpec/DescribeClass:
|
179
250
|
Exclude:
|
@@ -185,7 +256,70 @@ RSpec/DescribeClass:
|
|
185
256
|
RSpec/FilePath:
|
186
257
|
Enabled: false
|
187
258
|
|
259
|
+
RSpec/NamedSubject:
|
260
|
+
Enabled: false
|
261
|
+
|
262
|
+
RSpec/MultipleExpectations:
|
263
|
+
Enabled: false
|
264
|
+
|
265
|
+
RSpec/ExampleLength:
|
266
|
+
Enabled: false
|
267
|
+
|
268
|
+
RSpec/HookArgument:
|
269
|
+
EnforcedStyle: implicit
|
270
|
+
|
271
|
+
RSpec/MessageSpies:
|
272
|
+
EnforcedStyle: receive
|
273
|
+
|
274
|
+
RSpec/NestedGroups:
|
275
|
+
Enabled: false
|
276
|
+
|
277
|
+
RSpec/VerifiedDoubles:
|
278
|
+
Enabled: false
|
279
|
+
|
280
|
+
RSpec/LeadingSubject:
|
281
|
+
Enabled: false
|
282
|
+
|
283
|
+
RSpec/ExpectInHook:
|
284
|
+
Enabled: false
|
285
|
+
|
286
|
+
RSpec/ReturnFromStub:
|
287
|
+
Enabled: false
|
288
|
+
|
289
|
+
RSpec/SubjectStub:
|
290
|
+
Enabled: false
|
291
|
+
|
292
|
+
RSpec/EmptyLineAfterSubject:
|
293
|
+
Enabled: false
|
294
|
+
|
295
|
+
RSpec/LetSetup:
|
296
|
+
Enabled: false
|
297
|
+
|
298
|
+
RSpec/ImplicitExpect:
|
299
|
+
EnforcedStyle: is_expected
|
300
|
+
|
301
|
+
RSpec/ScatteredLet:
|
302
|
+
Enabled: false
|
303
|
+
|
304
|
+
RSpec/ContextWording:
|
305
|
+
Enabled: false
|
306
|
+
|
188
307
|
Rails/Output:
|
189
308
|
Exclude:
|
190
309
|
- 'config/application.rb'
|
191
310
|
- 'config/initializers/asset_manifest_warning.rb'
|
311
|
+
|
312
|
+
Rails/DynamicFindBy:
|
313
|
+
Enabled: false
|
314
|
+
|
315
|
+
Rails/Presence:
|
316
|
+
Enabled: false
|
317
|
+
|
318
|
+
Capybara/CurrentPathExpectation:
|
319
|
+
Enabled: false
|
320
|
+
|
321
|
+
Naming/UncommunicativeMethodParamName:
|
322
|
+
Enabled: false
|
323
|
+
|
324
|
+
Style/ExpandPathArguments:
|
325
|
+
Enabled: false
|
data/.rubocop.yml
CHANGED
@@ -44,3 +44,15 @@ RSpec/InstanceVariable:
|
|
44
44
|
|
45
45
|
Style/FrozenStringLiteralComment:
|
46
46
|
Enabled: false
|
47
|
+
|
48
|
+
Naming/MemoizedInstanceVariableName:
|
49
|
+
Enabled: false
|
50
|
+
|
51
|
+
RSpec/MessageSpies:
|
52
|
+
Enabled: false
|
53
|
+
|
54
|
+
RSpec/BeforeAfterAll:
|
55
|
+
Enabled: false
|
56
|
+
|
57
|
+
Style/EmptyMethod:
|
58
|
+
EnforcedStyle: compact
|
@@ -31,3 +31,24 @@ Adds the following header to the request:
|
|
31
31
|
```
|
32
32
|
|
33
33
|
Which is the base64 encoded credentials "username:password".
|
34
|
+
|
35
|
+
# Reauthenticate
|
36
|
+
|
37
|
+
The current implementation can only offer reauthenticate for _client access tokens_. For this to work the following has to be given:
|
38
|
+
|
39
|
+
* You have configured and implemented `LHC::Auth.refresh_client_token = -> { TokenRefreshUtil.client_access_token(true) }` which when called will force a refresh of the token and return the new value. It is also expected that this implementation will handle invalidating caches if necessary.
|
40
|
+
* Your interceptors contain `LHC::Auth` and `LHC::Retry`, whereas `LHC::Retry` comes _after_ `LHC::Auth` in the chain.
|
41
|
+
|
42
|
+
## Bearer Authentication with client access token
|
43
|
+
|
44
|
+
Reauthentication will be initiated if:
|
45
|
+
|
46
|
+
* setup is correct
|
47
|
+
* `response.success?` is false and an `LHC::Unauthorized` was observed
|
48
|
+
* reauthentication wasn't already attempted once
|
49
|
+
|
50
|
+
If this is the case, this happens:
|
51
|
+
|
52
|
+
* refresh the client token, by calling `refresh_client_token`
|
53
|
+
* the authentication header will be updated with the new token
|
54
|
+
* `LHC::Retry` will be triggered by adding `retry: { max: 1 }` to the request options
|
data/lhc.gemspec
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
$LOAD_PATH.push File.expand_path("../lib", __FILE__)
|
2
2
|
|
3
3
|
# Maintain your gem's version:
|
4
4
|
require "lhc/version"
|
@@ -18,20 +18,20 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.require_paths = ['lib']
|
19
19
|
|
20
20
|
s.requirements << 'Ruby >= 2.0.0'
|
21
|
-
s.required_ruby_version = '>= 2.
|
21
|
+
s.required_ruby_version = '>= 2.3.0'
|
22
22
|
|
23
|
-
s.add_dependency 'typhoeus', '>= 0.11'
|
24
23
|
s.add_dependency 'activesupport', '>= 4.2'
|
25
24
|
s.add_dependency 'addressable'
|
25
|
+
s.add_dependency 'typhoeus', '>= 0.11'
|
26
26
|
|
27
|
-
s.add_development_dependency 'rspec-rails', '>= 3.0.0'
|
28
|
-
s.add_development_dependency 'rails', '~> 4.2'
|
29
|
-
s.add_development_dependency 'webmock'
|
30
27
|
s.add_development_dependency 'geminabox'
|
31
|
-
s.add_development_dependency 'pry'
|
32
|
-
s.add_development_dependency 'rubocop', '~> 0.36.0'
|
33
|
-
s.add_development_dependency 'rubocop-rspec'
|
34
28
|
s.add_development_dependency 'prometheus-client', '~> 0.7.1'
|
29
|
+
s.add_development_dependency 'pry'
|
30
|
+
s.add_development_dependency 'rails', '~> 4.2'
|
31
|
+
s.add_development_dependency 'rspec-rails', '>= 3.0.0'
|
32
|
+
s.add_development_dependency 'rubocop', '~> 0.57.1'
|
33
|
+
s.add_development_dependency 'rubocop-rspec', '~> 1.26.0'
|
34
|
+
s.add_development_dependency 'webmock'
|
35
35
|
|
36
36
|
s.license = 'GPL-3'
|
37
37
|
end
|
data/lib/lhc/config.rb
CHANGED
@@ -10,7 +10,7 @@ class LHC::Config
|
|
10
10
|
|
11
11
|
def endpoint(name, url, options = {})
|
12
12
|
name = name.to_sym
|
13
|
-
|
13
|
+
raise 'Endpoint already exists for that name' if @endpoints[name]
|
14
14
|
@endpoints[name] = LHC::Endpoint.new(url, options)
|
15
15
|
end
|
16
16
|
|
@@ -20,7 +20,7 @@ class LHC::Config
|
|
20
20
|
|
21
21
|
def placeholder(name, value)
|
22
22
|
name = name.to_sym
|
23
|
-
|
23
|
+
raise 'Placeholder already exists for that name' if @placeholders[name]
|
24
24
|
@placeholders[name] = value
|
25
25
|
end
|
26
26
|
|
@@ -33,7 +33,7 @@ class LHC::Config
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def interceptors=(interceptors)
|
36
|
-
|
36
|
+
raise 'Default interceptors already set and can only be set once' if @interceptors
|
37
37
|
@interceptors = interceptors
|
38
38
|
end
|
39
39
|
|
data/lib/lhc/endpoint.rb
CHANGED
@@ -3,7 +3,8 @@ require 'addressable/template'
|
|
3
3
|
# An endpoint is an url that leads to a backend resource.
|
4
4
|
# The url can also be an url-template (https://tools.ietf.org/html/rfc6570).
|
5
5
|
class LHC::Endpoint
|
6
|
-
attr_accessor :url
|
6
|
+
attr_accessor :url
|
7
|
+
attr_writer :options
|
7
8
|
|
8
9
|
def initialize(url, options = nil)
|
9
10
|
self.url = url
|
@@ -22,7 +23,7 @@ class LHC::Endpoint
|
|
22
23
|
if expanded.variables.empty?
|
23
24
|
expanded.pattern
|
24
25
|
else
|
25
|
-
|
26
|
+
raise("Compilation incomplete. Unable to find value for #{expanded.variables.join(', ')}.")
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
@@ -99,7 +100,7 @@ class LHC::Endpoint
|
|
99
100
|
# Extracts the values from url and
|
100
101
|
# creates params according to template
|
101
102
|
def self.values_as_params(template, url)
|
102
|
-
|
103
|
+
raise("#{url} does not match the template: #{template}") if !match?(url, template)
|
103
104
|
new(template).values_as_params(url)
|
104
105
|
end
|
105
106
|
|
data/lib/lhc/interceptors.rb
CHANGED
@@ -16,7 +16,7 @@ class LHC::Interceptors
|
|
16
16
|
all.each do |interceptor|
|
17
17
|
result = interceptor.send(name)
|
18
18
|
if result.is_a? LHC::Response
|
19
|
-
|
19
|
+
raise 'Response already set from another interceptor' if @response
|
20
20
|
@response = interceptor.request.response = result
|
21
21
|
end
|
22
22
|
end
|
@@ -1,33 +1,96 @@
|
|
1
1
|
class LHC::Auth < LHC::Interceptor
|
2
|
+
include ActiveSupport::Configurable
|
3
|
+
config_accessor :refresh_client_token
|
2
4
|
|
3
5
|
def before_request
|
4
|
-
|
5
|
-
|
6
|
+
authenticate!
|
7
|
+
end
|
8
|
+
|
9
|
+
def after_response
|
10
|
+
return unless configuration_correct?
|
11
|
+
return unless reauthenticate?
|
12
|
+
reauthenticate!
|
6
13
|
end
|
7
14
|
|
8
15
|
private
|
9
16
|
|
10
|
-
def authenticate!
|
11
|
-
if
|
12
|
-
bearer_authentication!
|
13
|
-
elsif
|
14
|
-
basic_authentication!
|
17
|
+
def authenticate!
|
18
|
+
if auth_options[:bearer]
|
19
|
+
bearer_authentication!
|
20
|
+
elsif auth_options[:basic]
|
21
|
+
basic_authentication!
|
15
22
|
end
|
16
23
|
end
|
17
24
|
|
18
|
-
def basic_authentication!
|
19
|
-
auth =
|
25
|
+
def basic_authentication!
|
26
|
+
auth = auth_options[:basic]
|
20
27
|
credentials = "#{auth[:username]}:#{auth[:password]}"
|
21
|
-
set_authorization_header
|
28
|
+
set_authorization_header("Basic #{Base64.encode64(credentials).chomp}")
|
22
29
|
end
|
23
30
|
|
24
|
-
def bearer_authentication!
|
25
|
-
token =
|
31
|
+
def bearer_authentication!
|
32
|
+
token = auth_options[:bearer]
|
26
33
|
token = token.call if token.is_a?(Proc)
|
27
|
-
|
34
|
+
set_bearer_authorization_header(token)
|
28
35
|
end
|
29
36
|
|
30
|
-
|
37
|
+
# rubocop:disable Style/AccessorMethodName
|
38
|
+
def set_authorization_header(value)
|
31
39
|
request.headers['Authorization'] = value
|
32
40
|
end
|
41
|
+
|
42
|
+
def set_bearer_authorization_header(token)
|
43
|
+
set_authorization_header("Bearer #{token}")
|
44
|
+
end
|
45
|
+
# rubocop:enable Style/AccessorMethodName
|
46
|
+
|
47
|
+
def reauthenticate!
|
48
|
+
# refresh token and update header
|
49
|
+
token = refresh_client_token_option.call
|
50
|
+
set_bearer_authorization_header(token)
|
51
|
+
# trigger LHC::Retry and ensure we do not trigger reauthenticate!
|
52
|
+
# again should it fail another time
|
53
|
+
new_options = request.options.dup
|
54
|
+
new_options = new_options.merge(retry: { max: 1 })
|
55
|
+
new_options = new_options.merge(auth: { reauthenticated: true })
|
56
|
+
request.options = new_options
|
57
|
+
end
|
58
|
+
|
59
|
+
def reauthenticate?
|
60
|
+
!response.success? &&
|
61
|
+
!auth_options[:reauthenticated] &&
|
62
|
+
bearer_header_present? &&
|
63
|
+
LHC::Error.find(response) == LHC::Unauthorized
|
64
|
+
end
|
65
|
+
|
66
|
+
def bearer_header_present?
|
67
|
+
@has_bearer_header ||= request.headers['Authorization'] =~ /^Bearer [0-9a-f-]+$/i
|
68
|
+
end
|
69
|
+
|
70
|
+
def refresh_client_token_option
|
71
|
+
@refresh_client_token_option ||= auth_options[:refresh_client_token] || refresh_client_token
|
72
|
+
end
|
73
|
+
|
74
|
+
def all_interceptor_classes
|
75
|
+
@all_interceptors ||= LHC::Interceptors.new(request).all.map(&:class)
|
76
|
+
end
|
77
|
+
|
78
|
+
def auth_options
|
79
|
+
@auth_options ||= request.options[:auth].dup || {}
|
80
|
+
end
|
81
|
+
|
82
|
+
def configuration_correct?
|
83
|
+
# warn user about configs, only if refresh_client_token_option is set at all
|
84
|
+
refresh_client_token_option && refresh_client_token? && retry_interceptor?
|
85
|
+
end
|
86
|
+
|
87
|
+
def refresh_client_token?
|
88
|
+
return true if refresh_client_token_option.is_a?(Proc)
|
89
|
+
warn("[WARNING] The given refresh_client_token must be a Proc for reauthentication.")
|
90
|
+
end
|
91
|
+
|
92
|
+
def retry_interceptor?
|
93
|
+
return true if all_interceptor_classes.include?(LHC::Retry) && all_interceptor_classes.index(LHC::Retry) > all_interceptor_classes.index(self.class)
|
94
|
+
warn("[WARNING] Your interceptors must include LHC::Retry after LHC::Auth.")
|
95
|
+
end
|
33
96
|
end
|
@@ -15,7 +15,7 @@ class LHC::Caching < LHC::Interceptor
|
|
15
15
|
key = key(request, options[:key])
|
16
16
|
response_data = cache_for(options).fetch(key)
|
17
17
|
return unless response_data
|
18
|
-
logger
|
18
|
+
logger&.info "Served from cache: #{key}"
|
19
19
|
from_cache(request, response_data)
|
20
20
|
end
|
21
21
|
|
@@ -51,7 +51,7 @@ class LHC::Caching < LHC::Interceptor
|
|
51
51
|
# returns the request_options
|
52
52
|
# will map deprecated options to the new format
|
53
53
|
def options(request_options)
|
54
|
-
options = request_options[:cache] == true ? {} : request_options[:cache].dup
|
54
|
+
options = (request_options[:cache] == true) ? {} : request_options[:cache].dup
|
55
55
|
map_deprecated_options!(request_options, options)
|
56
56
|
options
|
57
57
|
end
|
@@ -6,14 +6,14 @@ class LHC::Logging < LHC::Interceptor
|
|
6
6
|
def before_request
|
7
7
|
return unless logger
|
8
8
|
logger.info(
|
9
|
-
"Before LHC request<#{request.object_id}> #{request.method.upcase} #{request.url} at #{
|
9
|
+
"Before LHC request<#{request.object_id}> #{request.method.upcase} #{request.url} at #{Time.now.iso8601} Params=#{request.params} Headers=#{request.headers}"
|
10
10
|
)
|
11
11
|
end
|
12
12
|
|
13
13
|
def after_response
|
14
14
|
return unless logger
|
15
15
|
logger.info(
|
16
|
-
"After LHC response for request<#{request.object_id}> #{request.method.upcase} #{request.url} at #{
|
16
|
+
"After LHC response for request<#{request.object_id}> #{request.method.upcase} #{request.url} at #{Time.now.iso8601} Time=#{response.time_ms}ms URL=#{response.effective_url}"
|
17
17
|
)
|
18
18
|
end
|
19
19
|
end
|
data/lib/lhc/request.rb
CHANGED
data/lib/lhc/response/data.rb
CHANGED
data/lib/lhc/version.rb
CHANGED
@@ -19,14 +19,14 @@ describe LHC do
|
|
19
19
|
LHC.delete('http://datastore/v2/feedbacks/12121')
|
20
20
|
end
|
21
21
|
|
22
|
-
it '
|
22
|
+
it 'makes response data available in a rails way' do
|
23
23
|
response = LHC.delete('http://datastore/v2/feedbacks/12121')
|
24
24
|
expect(response.data.recommended).to eq true
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'provides response headers' do
|
28
28
|
response = LHC.delete('http://datastore/v2/feedbacks/12121')
|
29
|
-
expect(response.headers).to
|
29
|
+
expect(response.headers).to be_present
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
@@ -22,14 +22,14 @@ describe LHC do
|
|
22
22
|
LHC.get(:feedbacks, params: parameters)
|
23
23
|
end
|
24
24
|
|
25
|
-
it '
|
25
|
+
it 'makes response data available in a rails way' do
|
26
26
|
response = LHC.get('http://datastore/v2/feedbacks', params: parameters)
|
27
27
|
expect(response.data.total).to eq 99
|
28
28
|
end
|
29
29
|
|
30
30
|
it 'provides response headers' do
|
31
31
|
response = LHC.get('http://datastore/v2/feedbacks', params: parameters)
|
32
|
-
expect(response.headers).to
|
32
|
+
expect(response.headers).to be_present
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
@@ -27,14 +27,14 @@ describe LHC do
|
|
27
27
|
LHC.post(:feedbacks, body: feedback)
|
28
28
|
end
|
29
29
|
|
30
|
-
it '
|
30
|
+
it 'makes response data available in a rails way' do
|
31
31
|
response = LHC.post('http://datastore/v2/feedbacks', body: feedback)
|
32
32
|
expect(response.data.source_id).to eq 'aaa'
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'provides response headers' do
|
36
36
|
response = LHC.post('http://datastore/v2/feedbacks', body: feedback)
|
37
|
-
expect(response.headers).to
|
37
|
+
expect(response.headers).to be_present
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
@@ -33,14 +33,14 @@ describe LHC do
|
|
33
33
|
LHC.put(:feedbacks, body: change)
|
34
34
|
end
|
35
35
|
|
36
|
-
it '
|
36
|
+
it 'makes response data available in a rails way' do
|
37
37
|
response = LHC.put('http://datastore/v2/feedbacks', body: change)
|
38
38
|
expect(response.data.recommended).to eq false
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'provides response headers' do
|
42
42
|
response = LHC.put('http://datastore/v2/feedbacks', body: change)
|
43
|
-
expect(response.headers).to
|
43
|
+
expect(response.headers).to be_present
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
data/spec/endpoint/match_spec.rb
CHANGED
@@ -16,7 +16,7 @@ describe LHC::Endpoint do
|
|
16
16
|
'http://local.ch/places/1/feedbacks.json' => 'http://local.ch/places/1/feedbacks.json?lang=en'
|
17
17
|
}.each do |template, url|
|
18
18
|
it "#{url} matches #{template}" do
|
19
|
-
expect(LHC::Endpoint.match?(url, template)).to be
|
19
|
+
expect(LHC::Endpoint.match?(url, template)).to be(true)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -31,7 +31,7 @@ describe LHC::Endpoint do
|
|
31
31
|
it "#{url} should not match #{template}" do
|
32
32
|
expect(
|
33
33
|
LHC::Endpoint.match?(url, template)
|
34
|
-
).
|
34
|
+
).to be(false)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -12,7 +12,7 @@ describe LHC::Endpoint do
|
|
12
12
|
it 'allows basic auth token in url, like used on github' do
|
13
13
|
stub_request(:get, "https://d123token:@api.github.com/search")
|
14
14
|
.to_return(body: {}.to_json)
|
15
|
-
expect(->{
|
15
|
+
expect(-> {
|
16
16
|
LHC.get("https://d123token:@api.github.com/search")
|
17
17
|
}).not_to raise_error
|
18
18
|
end
|
@@ -20,7 +20,7 @@ describe LHC::Endpoint do
|
|
20
20
|
it 'allows complete basic auth (username password) in url, like used for the gemserer' do
|
21
21
|
stub_request(:get, "https://name:password@gemserver.com")
|
22
22
|
.to_return(body: {}.to_json)
|
23
|
-
expect(->{
|
23
|
+
expect(-> {
|
24
24
|
LHC.get("https://name:password@gemserver.com")
|
25
25
|
}).not_to raise_error
|
26
26
|
end
|
data/spec/error/to_s_spec.rb
CHANGED
@@ -46,10 +46,10 @@ describe LHC::Error do
|
|
46
46
|
double('request',
|
47
47
|
method: 'GET',
|
48
48
|
url: 'http://example.com/sessions',
|
49
|
-
headers: { 'Bearer Token' => "aaaaaaaa-bbbb-cccc-dddd-eeee"},
|
49
|
+
headers: { 'Bearer Token' => "aaaaaaaa-bbbb-cccc-dddd-eeee" },
|
50
50
|
options: { followlocation: true,
|
51
|
-
auth: { bearer: "aaaaaaaa-bbbb-cccc-dddd-eeee"},
|
52
|
-
params: { limit: 20}, url: "http://example.com/sessions" })
|
51
|
+
auth: { bearer: "aaaaaaaa-bbbb-cccc-dddd-eeee" },
|
52
|
+
params: { limit: 20 }, url: "http://example.com/sessions" })
|
53
53
|
end
|
54
54
|
|
55
55
|
let(:response) do
|
@@ -4,12 +4,9 @@ describe LHC do
|
|
4
4
|
context 'interceptor' do
|
5
5
|
before(:each) do
|
6
6
|
class Services
|
7
|
-
def self.timing(_path, _time)
|
8
|
-
end
|
7
|
+
def self.timing(_path, _time); end
|
9
8
|
end
|
10
|
-
end
|
11
9
|
|
12
|
-
before(:each) do
|
13
10
|
class StatsTimingInterceptor < LHC::Interceptor
|
14
11
|
def after_response
|
15
12
|
uri = URI.parse(response.request.url)
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe LHC::Auth do
|
4
|
+
let(:bearer_token) { '123456' }
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
stub_request(:get, 'http://local.ch').with(headers: { 'Authorization' => "Bearer #{bearer_token}" })
|
8
|
+
end
|
9
|
+
|
10
|
+
context "configuration check not happening" do
|
11
|
+
let(:options) { { bearer: bearer_token } }
|
12
|
+
|
13
|
+
before(:each) { LHC.config.interceptors = [LHC::Auth, LHC::Retry] }
|
14
|
+
|
15
|
+
it "max_recovery_attempts is zero" do
|
16
|
+
expect_any_instance_of(described_class).not_to receive(:warn)
|
17
|
+
LHC.config.endpoint(:local, 'http://local.ch', auth: options.merge(max_recovery_attempts: 0))
|
18
|
+
LHC.get(:local)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "max_recovery_attempts is missing" do
|
22
|
+
expect_any_instance_of(described_class).not_to receive(:warn)
|
23
|
+
LHC.config.endpoint(:local, 'http://local.ch', auth: options)
|
24
|
+
LHC.get(:local)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "configuration check happening" do
|
29
|
+
let(:options) { { bearer: bearer_token, max_recovery_attempts: 1, refresh_client_token: -> { "here comes your refresh code" } } }
|
30
|
+
|
31
|
+
it "no warning with proper options" do
|
32
|
+
LHC.config.interceptors = [LHC::Auth, LHC::Retry]
|
33
|
+
LHC.config.endpoint(:local, 'http://local.ch', auth: options)
|
34
|
+
expect_any_instance_of(described_class).not_to receive(:warn)
|
35
|
+
LHC.get(:local)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "warn refresh_client_token is a string" do
|
39
|
+
LHC.config.interceptors = [LHC::Auth, LHC::Retry]
|
40
|
+
LHC.config.endpoint(:local, 'http://local.ch', auth: options.merge(refresh_client_token: bearer_token))
|
41
|
+
expect_any_instance_of(described_class).to receive(:warn).with("[WARNING] The given refresh_client_token must be a Proc for reauthentication.")
|
42
|
+
LHC.get(:local)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "warn interceptors miss LHC::Retry" do
|
46
|
+
LHC.config.interceptors = [LHC::Auth]
|
47
|
+
LHC.config.endpoint(:local, 'http://local.ch', auth: options)
|
48
|
+
expect_any_instance_of(described_class).to receive(:warn).with("[WARNING] Your interceptors must include LHC::Retry after LHC::Auth.")
|
49
|
+
LHC.get(:local)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "warn interceptors LHC::Retry before LHC::Auth" do
|
53
|
+
LHC.config.interceptors = [LHC::Retry, LHC::Auth]
|
54
|
+
LHC.config.endpoint(:local, 'http://local.ch', auth: options)
|
55
|
+
expect_any_instance_of(described_class).to receive(:warn).with("[WARNING] Your interceptors must include LHC::Retry after LHC::Auth.")
|
56
|
+
LHC.get(:local)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe LHC::Auth do
|
4
|
+
let(:initial_token) { '123456' }
|
5
|
+
let(:refresh_token) { 'abcdef' }
|
6
|
+
let(:options) { { bearer: initial_token, refresh_client_token: -> { refresh_token } } }
|
7
|
+
let!(:auth_failing) do
|
8
|
+
stub_request(:get, 'http://local.ch')
|
9
|
+
.with(headers: { 'Authorization' => "Bearer #{initial_token}" })
|
10
|
+
.to_return(status: 401, body: "{}") # LHC::Unauthorized
|
11
|
+
end
|
12
|
+
let!(:auth_suceeding_after_recovery) do
|
13
|
+
stub_request(:get, 'http://local.ch')
|
14
|
+
.with(headers: { 'Authorization' => "Bearer #{refresh_token}" })
|
15
|
+
end
|
16
|
+
|
17
|
+
before(:each) do
|
18
|
+
LHC.config.interceptors = [LHC::Auth, LHC::Retry]
|
19
|
+
end
|
20
|
+
|
21
|
+
it "recovery is attempted" do
|
22
|
+
LHC.config.endpoint(:local, 'http://local.ch', auth: options)
|
23
|
+
# the retried request (with updated Bearer), that should work
|
24
|
+
LHC.get(:local)
|
25
|
+
expect(auth_suceeding_after_recovery).to have_been_made.once
|
26
|
+
end
|
27
|
+
|
28
|
+
it "recovery is not attempted again when the request has reauthenticated: true " do
|
29
|
+
LHC.config.endpoint(:local, 'http://local.ch', auth: options.merge(reauthenticated: true))
|
30
|
+
expect { LHC.get(:local) }.to raise_error(LHC::Unauthorized)
|
31
|
+
end
|
32
|
+
end
|
@@ -5,14 +5,12 @@ describe LHC::Caching do
|
|
5
5
|
LHC.config.interceptors = [LHC::Caching]
|
6
6
|
LHC::Caching.cache = Rails.cache
|
7
7
|
Rails.cache.clear
|
8
|
-
end
|
9
|
-
|
10
|
-
let!(:stub) { stub_request(:post, 'http://local.ch').to_return(status: 200, body: 'The Website') }
|
11
8
|
|
12
|
-
before(:each) do
|
13
9
|
LHC.config.endpoint(:local, 'http://local.ch', cache: { expires_in: 5.minutes })
|
14
10
|
end
|
15
11
|
|
12
|
+
let!(:stub) { stub_request(:post, 'http://local.ch').to_return(status: 200, body: 'The Website') }
|
13
|
+
|
16
14
|
it 'only caches GET requests by default' do
|
17
15
|
expect(Rails.cache).not_to receive(:write)
|
18
16
|
LHC.post(:local)
|
@@ -4,15 +4,14 @@ require 'rails_helper'
|
|
4
4
|
# we need a class where we can setup method expectations
|
5
5
|
# with `expect_any_instance`
|
6
6
|
class CacheMock
|
7
|
-
def fetch(*_)
|
8
|
-
end
|
7
|
+
def fetch(*_); end
|
9
8
|
|
10
|
-
def write(*_)
|
11
|
-
end
|
9
|
+
def write(*_); end
|
12
10
|
end
|
13
11
|
|
14
12
|
describe LHC::Caching do
|
15
13
|
let(:default_cache) { LHC::Caching.cache }
|
14
|
+
|
16
15
|
before(:each) do
|
17
16
|
stub_request(:get, 'http://local.ch').to_return(status: 200, body: 'The Website')
|
18
17
|
LHC.config.interceptors = [LHC::Caching]
|
@@ -26,7 +25,7 @@ describe LHC::Caching do
|
|
26
25
|
expect(lambda {
|
27
26
|
LHC.get('http://local.ch', cache: true, cache_expires_in: 5.minutes, cache_key: 'key', cache_race_condition_ttl: 15.seconds)
|
28
27
|
}).to output(
|
29
|
-
|
28
|
+
/Cache options have changed! cache_expires_in, cache_key, cache_race_condition_ttl are deprecated and will be removed in future versions./
|
30
29
|
).to_stderr
|
31
30
|
end
|
32
31
|
|
@@ -5,11 +5,9 @@ describe LHC::Monitoring do
|
|
5
5
|
let(:endpoint_configuration) { LHC.config.endpoint(:local, 'http://local.ch') }
|
6
6
|
|
7
7
|
module Statsd
|
8
|
-
def self.count(_path, _value)
|
9
|
-
end
|
8
|
+
def self.count(_path, _value); end
|
10
9
|
|
11
|
-
def self.timing(_path, _value)
|
12
|
-
end
|
10
|
+
def self.timing(_path, _value); end
|
13
11
|
end
|
14
12
|
|
15
13
|
before(:each) do
|
@@ -100,7 +100,7 @@ describe LHC::Zipkin do
|
|
100
100
|
|
101
101
|
it 'does register a new span' do
|
102
102
|
# ensure a span was registered, by checking call on span
|
103
|
-
expect_any_instance_of(described_class).to receive(:span).at_least(
|
103
|
+
expect_any_instance_of(described_class).to receive(:span).at_least(:once).and_call_original
|
104
104
|
LHC.get(:local)
|
105
105
|
end
|
106
106
|
end
|
@@ -3,6 +3,7 @@ require 'rails_helper'
|
|
3
3
|
describe LHC::Request do
|
4
4
|
context 'ignoring LHC::NotFound' do
|
5
5
|
let(:response) { LHC.get('http://local.ch', ignored_errors: [LHC::NotFound]) }
|
6
|
+
|
6
7
|
before { stub_request(:get, 'http://local.ch').to_return(status: 404) }
|
7
8
|
|
8
9
|
it 'does not raise an error' do
|
@@ -5,7 +5,7 @@ describe LHC::Response do
|
|
5
5
|
let(:response_success) { LHC::Response.new(Typhoeus::Response.new(response_code: 200, mock: true), nil) }
|
6
6
|
let(:response_error) { LHC::Response.new(Typhoeus::Response.new(response_code: 404, mock: true), nil) }
|
7
7
|
|
8
|
-
it { expect(response_success
|
9
|
-
it { expect(response_error
|
8
|
+
it { expect(response_success).to be_success }
|
9
|
+
it { expect(response_error).not_to be_success }
|
10
10
|
end
|
11
11
|
end
|
data/spec/response/time_spec.rb
CHANGED
@@ -11,7 +11,7 @@ describe LHC::Response do
|
|
11
11
|
expect(response.time).to eq time * 1000
|
12
12
|
end
|
13
13
|
|
14
|
-
it 'provides response time in
|
14
|
+
it 'provides response time in miliseconds' do
|
15
15
|
response = LHC::Response.new(raw_response, nil)
|
16
16
|
expect(response.time_ms).to eq time
|
17
17
|
end
|
data/spec/support/zipkin_mock.rb
CHANGED
metadata
CHANGED
@@ -1,87 +1,87 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lhc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 9.
|
4
|
+
version: 9.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- https://github.com/local-ch/lhc/contributors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-06-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '4.2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '4.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: addressable
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: typhoeus
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
47
|
+
version: '0.11'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
54
|
+
version: '0.11'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: geminabox
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: prometheus-client
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 0.7.1
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 0.7.1
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: pry
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - ">="
|
@@ -95,75 +95,75 @@ dependencies:
|
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: rails
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - "
|
101
|
+
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
103
|
+
version: '4.2'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - "
|
108
|
+
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
110
|
+
version: '4.2'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
112
|
+
name: rspec-rails
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - ">="
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
117
|
+
version: 3.0.0
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
124
|
+
version: 3.0.0
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: rubocop
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
129
|
- - "~>"
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: 0.
|
131
|
+
version: 0.57.1
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: 0.
|
138
|
+
version: 0.57.1
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: rubocop-rspec
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- - "
|
143
|
+
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version:
|
145
|
+
version: 1.26.0
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- - "
|
150
|
+
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
152
|
+
version: 1.26.0
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
154
|
+
name: webmock
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
|
-
- - "
|
157
|
+
- - ">="
|
158
158
|
- !ruby/object:Gem::Version
|
159
|
-
version: 0
|
159
|
+
version: '0'
|
160
160
|
type: :development
|
161
161
|
prerelease: false
|
162
162
|
version_requirements: !ruby/object:Gem::Requirement
|
163
163
|
requirements:
|
164
|
-
- - "
|
164
|
+
- - ">="
|
165
165
|
- !ruby/object:Gem::Version
|
166
|
-
version: 0
|
166
|
+
version: '0'
|
167
167
|
description: 'Rails gem for HTTP: Wraps typhoeus and provides additional features
|
168
168
|
(like interceptors)'
|
169
169
|
email:
|
@@ -302,6 +302,8 @@ files:
|
|
302
302
|
- spec/interceptors/after_response_spec.rb
|
303
303
|
- spec/interceptors/auth/basic_auth_spec.rb
|
304
304
|
- spec/interceptors/auth/bearer_spec.rb
|
305
|
+
- spec/interceptors/auth/reauthentication_configuration_spec.rb
|
306
|
+
- spec/interceptors/auth/reauthentication_spec.rb
|
305
307
|
- spec/interceptors/before_request_spec.rb
|
306
308
|
- spec/interceptors/before_response_spec.rb
|
307
309
|
- spec/interceptors/caching/hydra_spec.rb
|
@@ -363,7 +365,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
363
365
|
requirements:
|
364
366
|
- - ">="
|
365
367
|
- !ruby/object:Gem::Version
|
366
|
-
version: 2.
|
368
|
+
version: 2.3.0
|
367
369
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
368
370
|
requirements:
|
369
371
|
- - ">="
|
@@ -372,7 +374,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
372
374
|
requirements:
|
373
375
|
- Ruby >= 2.0.0
|
374
376
|
rubyforge_project:
|
375
|
-
rubygems_version: 2.6.
|
377
|
+
rubygems_version: 2.6.14
|
376
378
|
signing_key:
|
377
379
|
specification_version: 4
|
378
380
|
summary: LocalHttpClient
|
@@ -440,6 +442,8 @@ test_files:
|
|
440
442
|
- spec/interceptors/after_response_spec.rb
|
441
443
|
- spec/interceptors/auth/basic_auth_spec.rb
|
442
444
|
- spec/interceptors/auth/bearer_spec.rb
|
445
|
+
- spec/interceptors/auth/reauthentication_configuration_spec.rb
|
446
|
+
- spec/interceptors/auth/reauthentication_spec.rb
|
443
447
|
- spec/interceptors/before_request_spec.rb
|
444
448
|
- spec/interceptors/before_response_spec.rb
|
445
449
|
- spec/interceptors/caching/hydra_spec.rb
|