sealights-rspec-agent 2.0.4 → 2.0.5
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/agent/config.rb +6 -6
- data/agent/dependencies/faraday-0.17.0/LICENSE.md +20 -0
- data/agent/dependencies/faraday-0.17.0/README.md +384 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday.rb +248 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter.rb +55 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/em_http.rb +243 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/em_synchrony.rb +106 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/em_synchrony/parallel_manager.rb +66 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/excon.rb +82 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/httpclient.rb +128 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/net_http.rb +152 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/net_http_persistent.rb +68 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/patron.rb +95 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/rack.rb +58 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/sl_em_http_ssl_patch.rb +56 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/test.rb +213 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/adapter/typhoeus.rb +12 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/autoload.rb +84 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/connection.rb +484 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/error.rb +66 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/middleware.rb +37 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/options.rb +373 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/parameters.rb +198 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/rack_builder.rb +237 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/request.rb +114 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/request/authorization.rb +41 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/request/basic_authentication.rb +13 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/request/instrumentation.rb +36 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/request/multipart.rb +68 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/request/retry.rb +212 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/request/token_authentication.rb +15 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/request/url_encoded.rb +36 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/response.rb +97 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/response/logger.rb +80 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/response/raise_error.rb +21 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/upload_io.rb +67 -0
- data/agent/dependencies/faraday-0.17.0/lib/faraday/utils.rb +326 -0
- data/agent/dependencies/jwt-2.2.1/AUTHORS +84 -0
- data/agent/dependencies/jwt-2.2.1/Appraisals +14 -0
- data/agent/dependencies/jwt-2.2.1/CHANGELOG.md +570 -0
- data/agent/dependencies/jwt-2.2.1/Gemfile +3 -0
- data/agent/dependencies/jwt-2.2.1/LICENSE +7 -0
- data/agent/dependencies/jwt-2.2.1/README.md +489 -0
- data/agent/dependencies/jwt-2.2.1/Rakefile +11 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt.rb +30 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt/algos/ecdsa.rb +35 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt/algos/eddsa.rb +23 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt/algos/hmac.rb +33 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt/algos/ps.rb +43 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt/algos/rsa.rb +19 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt/algos/unsupported.rb +16 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt/base64.rb +19 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt/claims_validator.rb +33 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt/decode.rb +100 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt/default_options.rb +15 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt/encode.rb +68 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt/error.rb +20 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt/json.rb +18 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt/jwk.rb +31 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt/jwk/key_finder.rb +57 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt/jwk/rsa.rb +47 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt/security_utils.rb +57 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt/signature.rb +52 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt/verify.rb +98 -0
- data/agent/dependencies/jwt-2.2.1/lib/jwt/version.rb +24 -0
- data/agent/dependencies/jwt-2.2.1/ruby-jwt.gemspec +34 -0
- data/agent/dependencies/multipart-post-2.1.1/Gemfile +6 -0
- data/agent/dependencies/multipart-post-2.1.1/History.txt +64 -0
- data/agent/dependencies/multipart-post-2.1.1/LICENSE +21 -0
- data/agent/dependencies/multipart-post-2.1.1/Manifest.txt +9 -0
- data/agent/dependencies/multipart-post-2.1.1/README.md +127 -0
- data/agent/dependencies/multipart-post-2.1.1/Rakefile +6 -0
- data/agent/dependencies/multipart-post-2.1.1/lib/composite_io.rb +108 -0
- data/agent/dependencies/multipart-post-2.1.1/lib/multipart_post.rb +9 -0
- data/agent/dependencies/multipart-post-2.1.1/lib/multipartable.rb +48 -0
- data/agent/dependencies/multipart-post-2.1.1/lib/net/http/post/multipart.rb +28 -0
- data/agent/dependencies/multipart-post-2.1.1/lib/parts.rb +126 -0
- data/agent/dependencies/multipart-post-2.1.1/multipart-post.gemspec +23 -0
- data/agent/http_client.rb +46 -0
- data/agent/listener.rb +1 -1
- data/agent/sealights-rspec-agent.rb +2 -2
- data/agent/tia.rb +5 -1
- metadata +80 -3
- data/agent/rest-client-wrapper.rb +0 -27
@@ -0,0 +1,41 @@
|
|
1
|
+
module SLFaraday
|
2
|
+
class Request::Authorization < SLFaraday::Middleware
|
3
|
+
KEY = "Authorization".freeze unless defined? KEY
|
4
|
+
|
5
|
+
# Public
|
6
|
+
def self.header(type, token)
|
7
|
+
case token
|
8
|
+
when String, Symbol
|
9
|
+
"#{type} #{token}"
|
10
|
+
when Hash
|
11
|
+
build_hash(type.to_s, token)
|
12
|
+
else
|
13
|
+
raise ArgumentError, "Can't build an Authorization #{type} header from #{token.inspect}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Internal
|
18
|
+
def self.build_hash(type, hash)
|
19
|
+
comma = ", "
|
20
|
+
values = []
|
21
|
+
hash.each do |key, value|
|
22
|
+
values << "#{key}=#{value.to_s.inspect}"
|
23
|
+
end
|
24
|
+
"#{type} #{values * comma}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(app, type, token)
|
28
|
+
@header_value = self.class.header(type, token)
|
29
|
+
super(app)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Public
|
33
|
+
def call(env)
|
34
|
+
unless env.request_headers[KEY]
|
35
|
+
env.request_headers[KEY] = @header_value
|
36
|
+
end
|
37
|
+
@app.call(env)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
3
|
+
module SLFaraday
|
4
|
+
class Request::BasicAuthentication < Request.load_middleware(:authorization)
|
5
|
+
# Public
|
6
|
+
def self.header(login, pass)
|
7
|
+
value = Base64.encode64([login, pass].join(':'))
|
8
|
+
value.gsub!("\n", '')
|
9
|
+
super(:Basic, value)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module SLFaraday
|
2
|
+
class Request::Instrumentation < SLFaraday::Middleware
|
3
|
+
class Options < SLFaraday::Options.new(:name, :instrumenter)
|
4
|
+
def name
|
5
|
+
self[:name] ||= 'request.faraday'
|
6
|
+
end
|
7
|
+
|
8
|
+
def instrumenter
|
9
|
+
self[:instrumenter] ||= ActiveSupport::Notifications
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Public: Instruments requests using Active Support.
|
14
|
+
#
|
15
|
+
# Measures time spent only for synchronous requests.
|
16
|
+
#
|
17
|
+
# Examples
|
18
|
+
#
|
19
|
+
# ActiveSupport::Notifications.subscribe('request.faraday') do |name, starts, ends, _, env|
|
20
|
+
# url = env[:url]
|
21
|
+
# http_method = env[:method].to_s.upcase
|
22
|
+
# duration = ends - starts
|
23
|
+
# $stderr.puts '[%s] %s %s (%.3f s)' % [url.host, http_method, url.request_uri, duration]
|
24
|
+
# end
|
25
|
+
def initialize(app, options = nil)
|
26
|
+
super(app)
|
27
|
+
@name, @instrumenter = Options.from(options).values_at(:name, :instrumenter)
|
28
|
+
end
|
29
|
+
|
30
|
+
def call(env)
|
31
|
+
@instrumenter.instrument(@name, env) do
|
32
|
+
@app.call(env)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require File.expand_path("../url_encoded", __FILE__)
|
2
|
+
require 'securerandom'
|
3
|
+
|
4
|
+
module SLFaraday
|
5
|
+
class Request::Multipart < Request::UrlEncoded
|
6
|
+
self.mime_type = 'multipart/form-data'.freeze
|
7
|
+
DEFAULT_BOUNDARY_PREFIX = "-----------RubyMultipartPost".freeze unless defined? DEFAULT_BOUNDARY_PREFIX
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
match_content_type(env) do |params|
|
11
|
+
env.request.boundary ||= unique_boundary
|
12
|
+
env.request_headers[CONTENT_TYPE] += "; boundary=#{env.request.boundary}"
|
13
|
+
env.body = create_multipart(env, params)
|
14
|
+
end
|
15
|
+
@app.call env
|
16
|
+
end
|
17
|
+
|
18
|
+
def process_request?(env)
|
19
|
+
type = request_type(env)
|
20
|
+
env.body.respond_to?(:each_key) and !env.body.empty? and (
|
21
|
+
(type.empty? and has_multipart?(env.body)) or
|
22
|
+
type == self.class.mime_type
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def has_multipart?(obj)
|
27
|
+
# string is an enum in 1.8, returning list of itself
|
28
|
+
if obj.respond_to?(:each) && !obj.is_a?(String)
|
29
|
+
(obj.respond_to?(:values) ? obj.values : obj).each do |val|
|
30
|
+
return true if (val.respond_to?(:content_type) || has_multipart?(val))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
false
|
34
|
+
end
|
35
|
+
|
36
|
+
def create_multipart(env, params)
|
37
|
+
boundary = env.request.boundary
|
38
|
+
parts = process_params(params) do |key, value|
|
39
|
+
SLFaraday::Parts::Part.new(boundary, key, value)
|
40
|
+
end
|
41
|
+
parts << SLFaraday::Parts::EpiloguePart.new(boundary)
|
42
|
+
|
43
|
+
body = SLFaraday::CompositeReadIO.new(parts)
|
44
|
+
env.request_headers[SLFaraday::Env::ContentLength] = body.length.to_s
|
45
|
+
return body
|
46
|
+
end
|
47
|
+
|
48
|
+
def unique_boundary
|
49
|
+
"#{DEFAULT_BOUNDARY_PREFIX}-#{SecureRandom.hex}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def process_params(params, prefix = nil, pieces = nil, &block)
|
53
|
+
params.inject(pieces || []) do |all, (key, value)|
|
54
|
+
key = "#{prefix}[#{key}]" if prefix
|
55
|
+
|
56
|
+
case value
|
57
|
+
when Array
|
58
|
+
values = value.inject([]) { |a,v| a << [nil, v] }
|
59
|
+
process_params(values, key, all, &block)
|
60
|
+
when Hash
|
61
|
+
process_params(value, key, all, &block)
|
62
|
+
else
|
63
|
+
all << block.call(key, value)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,212 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module SLFaraday
|
4
|
+
# Catches exceptions and retries each request a limited number of times.
|
5
|
+
#
|
6
|
+
# By default, it retries 2 times and handles only timeout exceptions. It can
|
7
|
+
# be configured with an arbitrary number of retries, a list of exceptions to
|
8
|
+
# handle, a retry interval, a percentage of randomness to add to the retry
|
9
|
+
# interval, and a backoff factor.
|
10
|
+
#
|
11
|
+
# Examples
|
12
|
+
#
|
13
|
+
# Faraday.new do |conn|
|
14
|
+
# conn.request :retry, max: 2, interval: 0.05,
|
15
|
+
# interval_randomness: 0.5, backoff_factor: 2,
|
16
|
+
# exceptions: [CustomException, 'Timeout::Error']
|
17
|
+
# conn.adapter ...
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# This example will result in a first interval that is random between 0.05 and 0.075 and a second
|
21
|
+
# interval that is random between 0.1 and 0.15
|
22
|
+
#
|
23
|
+
class Request::Retry < SLFaraday::Middleware
|
24
|
+
|
25
|
+
DEFAULT_EXCEPTIONS = [Errno::ETIMEDOUT, 'Timeout::Error', Error::TimeoutError, SLFaraday::Error::RetriableResponse].freeze
|
26
|
+
IDEMPOTENT_METHODS = [:delete, :get, :head, :options, :put]
|
27
|
+
|
28
|
+
class Options < SLFaraday::Options.new(:max, :interval, :max_interval, :interval_randomness,
|
29
|
+
:backoff_factor, :exceptions, :methods, :retry_if, :retry_block,
|
30
|
+
:retry_statuses)
|
31
|
+
|
32
|
+
DEFAULT_CHECK = lambda { |env,exception| false }
|
33
|
+
|
34
|
+
def self.from(value)
|
35
|
+
if Integer === value
|
36
|
+
new(value)
|
37
|
+
else
|
38
|
+
super(value)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def max
|
43
|
+
(self[:max] ||= 2).to_i
|
44
|
+
end
|
45
|
+
|
46
|
+
def interval
|
47
|
+
(self[:interval] ||= 0).to_f
|
48
|
+
end
|
49
|
+
|
50
|
+
def max_interval
|
51
|
+
(self[:max_interval] ||= Float::MAX).to_f
|
52
|
+
end
|
53
|
+
|
54
|
+
def interval_randomness
|
55
|
+
(self[:interval_randomness] ||= 0).to_f
|
56
|
+
end
|
57
|
+
|
58
|
+
def backoff_factor
|
59
|
+
(self[:backoff_factor] ||= 1).to_f
|
60
|
+
end
|
61
|
+
|
62
|
+
def exceptions
|
63
|
+
Array(self[:exceptions] ||= DEFAULT_EXCEPTIONS)
|
64
|
+
end
|
65
|
+
|
66
|
+
def methods
|
67
|
+
Array(self[:methods] ||= IDEMPOTENT_METHODS)
|
68
|
+
end
|
69
|
+
|
70
|
+
def retry_if
|
71
|
+
self[:retry_if] ||= DEFAULT_CHECK
|
72
|
+
end
|
73
|
+
|
74
|
+
def retry_block
|
75
|
+
self[:retry_block] ||= Proc.new {}
|
76
|
+
end
|
77
|
+
|
78
|
+
def retry_statuses
|
79
|
+
Array(self[:retry_statuses] ||= [])
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Public: Initialize middleware
|
84
|
+
#
|
85
|
+
# Options:
|
86
|
+
# max - Maximum number of retries (default: 2)
|
87
|
+
# interval - Pause in seconds between retries (default: 0)
|
88
|
+
# interval_randomness - The maximum random interval amount expressed
|
89
|
+
# as a float between 0 and 1 to use in addition to the
|
90
|
+
# interval. (default: 0)
|
91
|
+
# max_interval - An upper limit for the interval (default: Float::MAX)
|
92
|
+
# backoff_factor - The amount to multiple each successive retry's
|
93
|
+
# interval amount by in order to provide backoff
|
94
|
+
# (default: 1)
|
95
|
+
# exceptions - The list of exceptions to handle. Exceptions can be
|
96
|
+
# given as Class, Module, or String. (default:
|
97
|
+
# [Errno::ETIMEDOUT, 'Timeout::Error',
|
98
|
+
# Error::TimeoutError, Faraday::Error::RetriableResponse])
|
99
|
+
# methods - A list of HTTP methods to retry without calling retry_if. Pass
|
100
|
+
# an empty Array to call retry_if for all exceptions.
|
101
|
+
# (defaults to the idempotent HTTP methods in IDEMPOTENT_METHODS)
|
102
|
+
# retry_if - block that will receive the env object and the exception raised
|
103
|
+
# and should decide if the code should retry still the action or
|
104
|
+
# not independent of the retry count. This would be useful
|
105
|
+
# if the exception produced is non-recoverable or if the
|
106
|
+
# the HTTP method called is not idempotent.
|
107
|
+
# (defaults to return false)
|
108
|
+
# retry_block - block that is executed after every retry. Request environment, middleware options,
|
109
|
+
# current number of retries and the exception is passed to the block as parameters.
|
110
|
+
def initialize(app, options = nil)
|
111
|
+
super(app)
|
112
|
+
@options = Options.from(options)
|
113
|
+
@errmatch = build_exception_matcher(@options.exceptions)
|
114
|
+
end
|
115
|
+
|
116
|
+
def calculate_sleep_amount(retries, env)
|
117
|
+
retry_after = calculate_retry_after(env)
|
118
|
+
retry_interval = calculate_retry_interval(retries)
|
119
|
+
|
120
|
+
return if retry_after && retry_after > @options.max_interval
|
121
|
+
|
122
|
+
retry_after && retry_after >= retry_interval ? retry_after : retry_interval
|
123
|
+
end
|
124
|
+
|
125
|
+
def call(env)
|
126
|
+
retries = @options.max
|
127
|
+
request_body = env[:body]
|
128
|
+
begin
|
129
|
+
env[:body] = request_body # after failure env[:body] is set to the response body
|
130
|
+
@app.call(env).tap do |resp|
|
131
|
+
raise SLFaraday::Error::RetriableResponse.new(nil, resp) if @options.retry_statuses.include?(resp.status)
|
132
|
+
end
|
133
|
+
rescue @errmatch => exception
|
134
|
+
if retries > 0 && retry_request?(env, exception)
|
135
|
+
retries -= 1
|
136
|
+
rewind_files(request_body)
|
137
|
+
@options.retry_block.call(env, @options, retries, exception)
|
138
|
+
if (sleep_amount = calculate_sleep_amount(retries + 1, env))
|
139
|
+
sleep sleep_amount
|
140
|
+
retry
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
if exception.is_a?(SLFaraday::Error::RetriableResponse)
|
145
|
+
exception.response
|
146
|
+
else
|
147
|
+
raise
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Private: construct an exception matcher object.
|
153
|
+
#
|
154
|
+
# An exception matcher for the rescue clause can usually be any object that
|
155
|
+
# responds to `===`, but for Ruby 1.8 it has to be a Class or Module.
|
156
|
+
def build_exception_matcher(exceptions)
|
157
|
+
matcher = Module.new
|
158
|
+
(class << matcher; self; end).class_eval do
|
159
|
+
define_method(:===) do |error|
|
160
|
+
exceptions.any? do |ex|
|
161
|
+
if ex.is_a? Module
|
162
|
+
error.is_a? ex
|
163
|
+
else
|
164
|
+
error.class.to_s == ex.to_s
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
matcher
|
170
|
+
end
|
171
|
+
|
172
|
+
private
|
173
|
+
|
174
|
+
def retry_request?(env, exception)
|
175
|
+
@options.methods.include?(env[:method]) || @options.retry_if.call(env, exception)
|
176
|
+
end
|
177
|
+
|
178
|
+
def rewind_files(body)
|
179
|
+
return unless body.is_a?(Hash)
|
180
|
+
body.each do |_, value|
|
181
|
+
if value.is_a? UploadIO
|
182
|
+
value.rewind
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# MDN spec for Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
|
188
|
+
def calculate_retry_after(env)
|
189
|
+
response_headers = env[:response_headers]
|
190
|
+
return unless response_headers
|
191
|
+
|
192
|
+
retry_after_value = env[:response_headers]["Retry-After"]
|
193
|
+
|
194
|
+
# Try to parse date from the header value
|
195
|
+
begin
|
196
|
+
datetime = DateTime.rfc2822(retry_after_value)
|
197
|
+
datetime.to_time - Time.now.utc
|
198
|
+
rescue ArgumentError
|
199
|
+
retry_after_value.to_f
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def calculate_retry_interval(retries)
|
204
|
+
retry_index = @options.max - retries
|
205
|
+
current_interval = @options.interval * (@options.backoff_factor ** retry_index)
|
206
|
+
current_interval = [current_interval, @options.max_interval].min
|
207
|
+
random_interval = rand * @options.interval_randomness.to_f * @options.interval
|
208
|
+
|
209
|
+
current_interval + random_interval
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module SLFaraday
|
2
|
+
class Request::TokenAuthentication < Request.load_middleware(:authorization)
|
3
|
+
# Public
|
4
|
+
def self.header(token, options = nil)
|
5
|
+
options ||= {}
|
6
|
+
options[:token] = token
|
7
|
+
super(:Token, options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(app, token, options = nil)
|
11
|
+
super(app, token, options)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module SLFaraday
|
2
|
+
class Request::UrlEncoded < SLFaraday::Middleware
|
3
|
+
CONTENT_TYPE = 'Content-Type'.freeze unless defined? CONTENT_TYPE
|
4
|
+
|
5
|
+
class << self
|
6
|
+
attr_accessor :mime_type
|
7
|
+
end
|
8
|
+
self.mime_type = 'application/x-www-form-urlencoded'.freeze
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
match_content_type(env) do |data|
|
12
|
+
params = SLFaraday::Utils::ParamsHash[data]
|
13
|
+
env.body = params.to_query(env.params_encoder)
|
14
|
+
end
|
15
|
+
@app.call env
|
16
|
+
end
|
17
|
+
|
18
|
+
def match_content_type(env)
|
19
|
+
if process_request?(env)
|
20
|
+
env.request_headers[CONTENT_TYPE] ||= self.class.mime_type
|
21
|
+
yield(env.body) unless env.body.respond_to?(:to_str)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def process_request?(env)
|
26
|
+
type = request_type(env)
|
27
|
+
env.body and (type.empty? or type == self.class.mime_type)
|
28
|
+
end
|
29
|
+
|
30
|
+
def request_type(env)
|
31
|
+
type = env.request_headers[CONTENT_TYPE].to_s
|
32
|
+
type = type.split(';', 2).first if type.index(';')
|
33
|
+
type
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module SLFaraday
|
4
|
+
class Response
|
5
|
+
# Used for simple response middleware.
|
6
|
+
class Middleware < SLFaraday::Middleware
|
7
|
+
def call(env)
|
8
|
+
@app.call(env).on_complete do |environment|
|
9
|
+
on_complete(environment)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Override this to modify the environment after the response has finished.
|
14
|
+
# Calls the `parse` method if defined
|
15
|
+
def on_complete(env)
|
16
|
+
env.body = parse(env.body) if respond_to?(:parse) && env.parse_body?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
extend Forwardable
|
21
|
+
extend MiddlewareRegistry
|
22
|
+
|
23
|
+
register_middleware File.expand_path('../response', __FILE__),
|
24
|
+
:raise_error => [:RaiseError, 'raise_error'],
|
25
|
+
:logger => [:Logger, 'logger']
|
26
|
+
|
27
|
+
def initialize(env = nil)
|
28
|
+
@env = Env.from(env) if env
|
29
|
+
@on_complete_callbacks = []
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_reader :env
|
33
|
+
|
34
|
+
def_delegators :env, :to_hash
|
35
|
+
|
36
|
+
def status
|
37
|
+
finished? ? env.status : nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def reason_phrase
|
41
|
+
finished? ? env.reason_phrase : nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def headers
|
45
|
+
finished? ? env.response_headers : {}
|
46
|
+
end
|
47
|
+
def_delegator :headers, :[]
|
48
|
+
|
49
|
+
def body
|
50
|
+
finished? ? env.body : nil
|
51
|
+
end
|
52
|
+
|
53
|
+
def finished?
|
54
|
+
!!env
|
55
|
+
end
|
56
|
+
|
57
|
+
def on_complete
|
58
|
+
if not finished?
|
59
|
+
@on_complete_callbacks << Proc.new
|
60
|
+
else
|
61
|
+
yield(env)
|
62
|
+
end
|
63
|
+
return self
|
64
|
+
end
|
65
|
+
|
66
|
+
def finish(env)
|
67
|
+
raise "response already finished" if finished?
|
68
|
+
@env = env.is_a?(Env) ? env : Env.from(env)
|
69
|
+
@on_complete_callbacks.each { |callback| callback.call(@env) }
|
70
|
+
return self
|
71
|
+
end
|
72
|
+
|
73
|
+
def success?
|
74
|
+
finished? && env.success?
|
75
|
+
end
|
76
|
+
|
77
|
+
# because @on_complete_callbacks cannot be marshalled
|
78
|
+
def marshal_dump
|
79
|
+
!finished? ? nil : {
|
80
|
+
:status => @env.status, :body => @env.body,
|
81
|
+
:response_headers => @env.response_headers
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
def marshal_load(env)
|
86
|
+
@env = Env.from(env)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Expand the env with more properties, without overriding existing ones.
|
90
|
+
# Useful for applying request params after restoring a marshalled Response.
|
91
|
+
def apply_request(request_env)
|
92
|
+
raise "response didn't finish yet" unless finished?
|
93
|
+
@env = Env.from(request_env).update(@env)
|
94
|
+
return self
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|