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,248 @@
|
|
1
|
+
require 'thread'
|
2
|
+
require 'cgi'
|
3
|
+
require 'set'
|
4
|
+
require 'forwardable'
|
5
|
+
|
6
|
+
# Public: This is the main namespace for Faraday. You can either use it to
|
7
|
+
# create Faraday::Connection objects, or access it directly.
|
8
|
+
#
|
9
|
+
# Examples
|
10
|
+
#
|
11
|
+
# Faraday.get "http://faraday.com"
|
12
|
+
#
|
13
|
+
# conn = Faraday.new "http://faraday.com"
|
14
|
+
# conn.get '/'
|
15
|
+
#
|
16
|
+
module SLFaraday
|
17
|
+
VERSION = "0.17.0"
|
18
|
+
|
19
|
+
class << self
|
20
|
+
# Public: Gets or sets the root path that Faraday is being loaded from.
|
21
|
+
# This is the root from where the libraries are auto-loaded from.
|
22
|
+
attr_accessor :root_path
|
23
|
+
|
24
|
+
# Public: Gets or sets the path that the Faraday libs are loaded from.
|
25
|
+
attr_accessor :lib_path
|
26
|
+
|
27
|
+
# Public: Gets or sets the Symbol key identifying a default Adapter to use
|
28
|
+
# for the default Faraday::Connection.
|
29
|
+
attr_reader :default_adapter
|
30
|
+
|
31
|
+
# Public: Sets the default Faraday::Connection for simple scripts that
|
32
|
+
# access the Faraday constant directly.
|
33
|
+
#
|
34
|
+
# Faraday.get "https://faraday.com"
|
35
|
+
attr_writer :default_connection
|
36
|
+
|
37
|
+
# Public: Tells faraday to ignore the environment proxy (http_proxy).
|
38
|
+
attr_accessor :ignore_env_proxy
|
39
|
+
|
40
|
+
# Public: Initializes a new Faraday::Connection.
|
41
|
+
#
|
42
|
+
# url - The optional String base URL to use as a prefix for all
|
43
|
+
# requests. Can also be the options Hash.
|
44
|
+
# options - The optional Hash used to configure this Faraday::Connection.
|
45
|
+
# Any of these values will be set on every request made, unless
|
46
|
+
# overridden for a specific request.
|
47
|
+
# :url - String base URL.
|
48
|
+
# :params - Hash of URI query unencoded key/value pairs.
|
49
|
+
# :headers - Hash of unencoded HTTP header key/value pairs.
|
50
|
+
# :request - Hash of request options.
|
51
|
+
# :ssl - Hash of SSL options.
|
52
|
+
# :proxy - Hash of Proxy options.
|
53
|
+
#
|
54
|
+
# Examples
|
55
|
+
#
|
56
|
+
# Faraday.new 'http://faraday.com'
|
57
|
+
#
|
58
|
+
# # http://faraday.com?page=1
|
59
|
+
# Faraday.new 'http://faraday.com', :params => {:page => 1}
|
60
|
+
#
|
61
|
+
# # same
|
62
|
+
#
|
63
|
+
# Faraday.new :url => 'http://faraday.com',
|
64
|
+
# :params => {:page => 1}
|
65
|
+
#
|
66
|
+
# Returns a Faraday::Connection.
|
67
|
+
def new(url = nil, options = nil)
|
68
|
+
block = block_given? ? Proc.new : nil
|
69
|
+
options = options ? default_connection_options.merge(options) : default_connection_options
|
70
|
+
SLFaraday::Connection.new(url, options, &block)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Internal: Requires internal Faraday libraries.
|
74
|
+
#
|
75
|
+
# *libs - One or more relative String names to Faraday classes.
|
76
|
+
#
|
77
|
+
# Returns nothing.
|
78
|
+
def require_libs(*libs)
|
79
|
+
libs.each do |lib|
|
80
|
+
require "#{lib_path}/#{lib}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Public: Updates default adapter while resetting
|
85
|
+
# #default_connection.
|
86
|
+
#
|
87
|
+
# Returns the new default_adapter.
|
88
|
+
def default_adapter=(adapter)
|
89
|
+
@default_connection = nil
|
90
|
+
@default_adapter = adapter
|
91
|
+
end
|
92
|
+
|
93
|
+
alias require_lib require_libs
|
94
|
+
|
95
|
+
def respond_to?(symbol, include_private = false)
|
96
|
+
default_connection.respond_to?(symbol, include_private) || super
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
# Internal: Proxies method calls on the Faraday constant to
|
101
|
+
# #default_connection.
|
102
|
+
def method_missing(name, *args, &block)
|
103
|
+
default_connection.send(name, *args, &block)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
self.ignore_env_proxy = false
|
108
|
+
self.root_path = File.expand_path "..", __FILE__
|
109
|
+
self.lib_path = File.expand_path "../faraday", __FILE__
|
110
|
+
self.default_adapter = :net_http
|
111
|
+
|
112
|
+
# Gets the default connection used for simple scripts.
|
113
|
+
#
|
114
|
+
# Returns a Faraday::Connection, configured with the #default_adapter.
|
115
|
+
def self.default_connection
|
116
|
+
@default_connection ||= Connection.new(default_connection_options)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Gets the default connection options used when calling SLFaraday#new.
|
120
|
+
#
|
121
|
+
# Returns a Faraday::ConnectionOptions.
|
122
|
+
def self.default_connection_options
|
123
|
+
@default_connection_options ||= ConnectionOptions.new
|
124
|
+
end
|
125
|
+
|
126
|
+
# Public: Sets the default options used when calling SLFaraday#new.
|
127
|
+
def self.default_connection_options=(options)
|
128
|
+
@default_connection = nil
|
129
|
+
@default_connection_options = ConnectionOptions.from(options)
|
130
|
+
end
|
131
|
+
|
132
|
+
unless const_defined? :Timer
|
133
|
+
require 'timeout'
|
134
|
+
Timer = Timeout
|
135
|
+
end
|
136
|
+
|
137
|
+
# Public: Adds the ability for other modules to register and lookup
|
138
|
+
# middleware classes.
|
139
|
+
module MiddlewareRegistry
|
140
|
+
# Public: Register middleware class(es) on the current module.
|
141
|
+
#
|
142
|
+
# mapping - A Hash mapping Symbol keys to classes. Classes can be expressed
|
143
|
+
# as fully qualified constant, or a Proc that will be lazily
|
144
|
+
# called to return the former.
|
145
|
+
#
|
146
|
+
# Examples
|
147
|
+
#
|
148
|
+
# module Faraday
|
149
|
+
# class Whatever
|
150
|
+
# # Middleware looked up by :foo returns Faraday::Whatever::Foo.
|
151
|
+
# register_middleware :foo => Foo
|
152
|
+
#
|
153
|
+
# # Middleware looked up by :bar returns Faraday::Whatever.const_get(:Bar)
|
154
|
+
# register_middleware :bar => :Bar
|
155
|
+
#
|
156
|
+
# # Middleware looked up by :baz requires 'baz' and returns Faraday::Whatever.const_get(:Baz)
|
157
|
+
# register_middleware :baz => [:Baz, 'baz']
|
158
|
+
# end
|
159
|
+
# end
|
160
|
+
#
|
161
|
+
# Returns nothing.
|
162
|
+
def register_middleware(autoload_path = nil, mapping = nil)
|
163
|
+
if mapping.nil?
|
164
|
+
mapping = autoload_path
|
165
|
+
autoload_path = nil
|
166
|
+
end
|
167
|
+
middleware_mutex do
|
168
|
+
@middleware_autoload_path = autoload_path if autoload_path
|
169
|
+
(@registered_middleware ||= {}).update(mapping)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# Public: Lookup middleware class with a registered Symbol shortcut.
|
174
|
+
#
|
175
|
+
# key - The Symbol key for the registered middleware.
|
176
|
+
#
|
177
|
+
# Examples
|
178
|
+
#
|
179
|
+
# module Faraday
|
180
|
+
# class Whatever
|
181
|
+
# register_middleware :foo => Foo
|
182
|
+
# end
|
183
|
+
# end
|
184
|
+
#
|
185
|
+
# Faraday::Whatever.lookup_middleware(:foo)
|
186
|
+
# # => Faraday::Whatever::Foo
|
187
|
+
#
|
188
|
+
# Returns a middleware Class.
|
189
|
+
def lookup_middleware(key)
|
190
|
+
load_middleware(key) ||
|
191
|
+
raise(SLFaraday::Error.new("#{key.inspect} is not registered on #{self}"))
|
192
|
+
end
|
193
|
+
|
194
|
+
def middleware_mutex(&block)
|
195
|
+
@middleware_mutex ||= begin
|
196
|
+
require 'monitor'
|
197
|
+
Monitor.new
|
198
|
+
end
|
199
|
+
@middleware_mutex.synchronize(&block)
|
200
|
+
end
|
201
|
+
|
202
|
+
def fetch_middleware(key)
|
203
|
+
defined?(@registered_middleware) && @registered_middleware[key]
|
204
|
+
end
|
205
|
+
|
206
|
+
def load_middleware(key)
|
207
|
+
value = fetch_middleware(key)
|
208
|
+
case value
|
209
|
+
when Module
|
210
|
+
value
|
211
|
+
when Symbol, String
|
212
|
+
middleware_mutex do
|
213
|
+
@registered_middleware[key] = const_get(value)
|
214
|
+
end
|
215
|
+
when Proc
|
216
|
+
middleware_mutex do
|
217
|
+
@registered_middleware[key] = value.call
|
218
|
+
end
|
219
|
+
when Array
|
220
|
+
middleware_mutex do
|
221
|
+
const, path = value
|
222
|
+
if root = @middleware_autoload_path
|
223
|
+
path = "#{root}/#{path}"
|
224
|
+
end
|
225
|
+
require(path)
|
226
|
+
@registered_middleware[key] = const
|
227
|
+
end
|
228
|
+
load_middleware(key)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def self.const_missing(name)
|
234
|
+
if name.to_sym == :Builder
|
235
|
+
warn "Faraday::Builder is now Faraday::RackBuilder."
|
236
|
+
const_set name, RackBuilder
|
237
|
+
else
|
238
|
+
super
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
require_libs "utils", "options", "connection", "rack_builder", "parameters",
|
243
|
+
"middleware", "adapter", "request", "response", "upload_io", "error"
|
244
|
+
|
245
|
+
if !ENV["FARADAY_NO_AUTOLOAD"]
|
246
|
+
require_lib 'autoload'
|
247
|
+
end
|
248
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module SLFaraday
|
2
|
+
# Public: This is a base class for all Faraday adapters. Adapters are
|
3
|
+
# responsible for fulfilling a Faraday request.
|
4
|
+
class Adapter < Middleware
|
5
|
+
CONTENT_LENGTH = 'Content-Length'.freeze
|
6
|
+
|
7
|
+
register_middleware File.expand_path('../adapter', __FILE__),
|
8
|
+
:test => [:Test, 'test'],
|
9
|
+
:net_http => [:NetHttp, 'net_http'],
|
10
|
+
:net_http_persistent => [:NetHttpPersistent, 'net_http_persistent'],
|
11
|
+
:typhoeus => [:Typhoeus, 'typhoeus'],
|
12
|
+
:patron => [:Patron, 'patron'],
|
13
|
+
:em_synchrony => [:EMSynchrony, 'em_synchrony'],
|
14
|
+
:em_http => [:EMHttp, 'em_http'],
|
15
|
+
:excon => [:Excon, 'excon'],
|
16
|
+
:rack => [:Rack, 'rack'],
|
17
|
+
:httpclient => [:HTTPClient, 'httpclient']
|
18
|
+
|
19
|
+
# Public: This module marks an Adapter as supporting parallel requests.
|
20
|
+
module Parallelism
|
21
|
+
attr_writer :supports_parallel
|
22
|
+
def supports_parallel?() @supports_parallel end
|
23
|
+
|
24
|
+
def inherited(subclass)
|
25
|
+
super
|
26
|
+
subclass.supports_parallel = self.supports_parallel?
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
extend Parallelism
|
31
|
+
self.supports_parallel = false
|
32
|
+
|
33
|
+
def initialize(app = nil, opts = {}, &block)
|
34
|
+
super(app)
|
35
|
+
@connection_options = opts
|
36
|
+
@config_block = block
|
37
|
+
end
|
38
|
+
|
39
|
+
def call(env)
|
40
|
+
env.clear_body if env.needs_body?
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def save_response(env, status, body, headers = nil, reason_phrase = nil)
|
46
|
+
env.status = status
|
47
|
+
env.body = body
|
48
|
+
env.reason_phrase = reason_phrase && reason_phrase.to_s.strip
|
49
|
+
env.response_headers = Utils::Headers.new.tap do |response_headers|
|
50
|
+
response_headers.update headers unless headers.nil?
|
51
|
+
yield(response_headers) if block_given?
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,243 @@
|
|
1
|
+
module SLFaraday
|
2
|
+
class Adapter
|
3
|
+
# EventMachine adapter is useful for either asynchronous requests
|
4
|
+
# when in EM reactor loop or for making parallel requests in
|
5
|
+
# synchronous code.
|
6
|
+
class EMHttp < SLFaraday::Adapter
|
7
|
+
module Options
|
8
|
+
def connection_config(env)
|
9
|
+
options = {}
|
10
|
+
configure_proxy(options, env)
|
11
|
+
configure_timeout(options, env)
|
12
|
+
configure_socket(options, env)
|
13
|
+
configure_ssl(options, env)
|
14
|
+
options
|
15
|
+
end
|
16
|
+
|
17
|
+
def request_config(env)
|
18
|
+
options = {
|
19
|
+
:body => read_body(env),
|
20
|
+
:head => env[:request_headers],
|
21
|
+
# :keepalive => true,
|
22
|
+
# :file => 'path/to/file', # stream data off disk
|
23
|
+
}
|
24
|
+
configure_compression(options, env)
|
25
|
+
options
|
26
|
+
end
|
27
|
+
|
28
|
+
def read_body(env)
|
29
|
+
body = env[:body]
|
30
|
+
body.respond_to?(:read) ? body.read : body
|
31
|
+
end
|
32
|
+
|
33
|
+
def configure_proxy(options, env)
|
34
|
+
if proxy = request_options(env)[:proxy]
|
35
|
+
options[:proxy] = {
|
36
|
+
:host => proxy[:uri].host,
|
37
|
+
:port => proxy[:uri].port,
|
38
|
+
:authorization => [proxy[:user], proxy[:password]]
|
39
|
+
}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def configure_socket(options, env)
|
44
|
+
if bind = request_options(env)[:bind]
|
45
|
+
options[:bind] = {
|
46
|
+
:host => bind[:host],
|
47
|
+
:port => bind[:port]
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def configure_ssl(options, env)
|
53
|
+
if env[:url].scheme == 'https' && env[:ssl]
|
54
|
+
options[:ssl] = {
|
55
|
+
:cert_chain_file => env[:ssl][:ca_file],
|
56
|
+
:verify_peer => env[:ssl].fetch(:verify, true)
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def configure_timeout(options, env)
|
62
|
+
timeout, open_timeout = request_options(env).values_at(:timeout, :open_timeout)
|
63
|
+
options[:connect_timeout] = options[:inactivity_timeout] = timeout
|
64
|
+
options[:connect_timeout] = open_timeout if open_timeout
|
65
|
+
end
|
66
|
+
|
67
|
+
def configure_compression(options, env)
|
68
|
+
if env[:method] == :get and not options[:head].key? 'accept-encoding'
|
69
|
+
options[:head]['accept-encoding'] = 'gzip, compressed'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def request_options(env)
|
74
|
+
env[:request]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
include Options
|
79
|
+
|
80
|
+
dependency 'em-http'
|
81
|
+
|
82
|
+
self.supports_parallel = true
|
83
|
+
|
84
|
+
def self.setup_parallel_manager(options = nil)
|
85
|
+
Manager.new
|
86
|
+
end
|
87
|
+
|
88
|
+
def call(env)
|
89
|
+
super
|
90
|
+
perform_request env
|
91
|
+
@app.call env
|
92
|
+
end
|
93
|
+
|
94
|
+
def perform_request(env)
|
95
|
+
if parallel?(env)
|
96
|
+
manager = env[:parallel_manager]
|
97
|
+
manager.add {
|
98
|
+
perform_single_request(env).
|
99
|
+
callback { env[:response].finish(env) }
|
100
|
+
}
|
101
|
+
else
|
102
|
+
unless EventMachine.reactor_running?
|
103
|
+
error = nil
|
104
|
+
# start EM, block until request is completed
|
105
|
+
EventMachine.run do
|
106
|
+
perform_single_request(env).
|
107
|
+
callback { EventMachine.stop }.
|
108
|
+
errback { |client|
|
109
|
+
error = error_message(client)
|
110
|
+
EventMachine.stop
|
111
|
+
}
|
112
|
+
end
|
113
|
+
raise_error(error) if error
|
114
|
+
else
|
115
|
+
# EM is running: instruct upstream that this is an async request
|
116
|
+
env[:parallel_manager] = true
|
117
|
+
perform_single_request(env).
|
118
|
+
callback { env[:response].finish(env) }.
|
119
|
+
errback {
|
120
|
+
# TODO: no way to communicate the error in async mode
|
121
|
+
raise NotImplementedError
|
122
|
+
}
|
123
|
+
end
|
124
|
+
end
|
125
|
+
rescue EventMachine::Connectify::CONNECTError => err
|
126
|
+
if err.message.include?("Proxy Authentication Required")
|
127
|
+
raise Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
|
128
|
+
else
|
129
|
+
raise Error::ConnectionFailed, err
|
130
|
+
end
|
131
|
+
rescue => err
|
132
|
+
if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
|
133
|
+
raise SLFaraday::SSLError, err
|
134
|
+
else
|
135
|
+
raise
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# TODO: reuse the connection to support pipelining
|
140
|
+
def perform_single_request(env)
|
141
|
+
req = create_request(env)
|
142
|
+
req.setup_request(env[:method], request_config(env)).callback { |client|
|
143
|
+
status = client.response_header.status
|
144
|
+
reason = client.response_header.http_reason
|
145
|
+
save_response(env, status, client.response, nil, reason) do |resp_headers|
|
146
|
+
client.response_header.each do |name, value|
|
147
|
+
resp_headers[name.to_sym] = value
|
148
|
+
end
|
149
|
+
end
|
150
|
+
}
|
151
|
+
end
|
152
|
+
|
153
|
+
def create_request(env)
|
154
|
+
EventMachine::HttpRequest.new(env[:url], connection_config(env).merge(@connection_options))
|
155
|
+
end
|
156
|
+
|
157
|
+
def error_message(client)
|
158
|
+
client.error or "request failed"
|
159
|
+
end
|
160
|
+
|
161
|
+
def raise_error(msg)
|
162
|
+
errklass = SLFaraday::Error::ClientError
|
163
|
+
if msg == Errno::ETIMEDOUT
|
164
|
+
errklass = SLFaraday::Error::TimeoutError
|
165
|
+
msg = "request timed out"
|
166
|
+
elsif msg == Errno::ECONNREFUSED
|
167
|
+
errklass = SLFaraday::Error::ConnectionFailed
|
168
|
+
msg = "connection refused"
|
169
|
+
elsif msg == "connection closed by server"
|
170
|
+
errklass = SLFaraday::Error::ConnectionFailed
|
171
|
+
end
|
172
|
+
raise errklass, msg
|
173
|
+
end
|
174
|
+
|
175
|
+
def parallel?(env)
|
176
|
+
!!env[:parallel_manager]
|
177
|
+
end
|
178
|
+
|
179
|
+
# The parallel manager is designed to start an EventMachine loop
|
180
|
+
# and block until all registered requests have been completed.
|
181
|
+
class Manager
|
182
|
+
def initialize
|
183
|
+
reset
|
184
|
+
end
|
185
|
+
|
186
|
+
def reset
|
187
|
+
@registered_procs = []
|
188
|
+
@num_registered = 0
|
189
|
+
@num_succeeded = 0
|
190
|
+
@errors = []
|
191
|
+
@running = false
|
192
|
+
end
|
193
|
+
|
194
|
+
def running?() @running end
|
195
|
+
|
196
|
+
def add
|
197
|
+
if running?
|
198
|
+
perform_request { yield }
|
199
|
+
else
|
200
|
+
@registered_procs << Proc.new
|
201
|
+
end
|
202
|
+
@num_registered += 1
|
203
|
+
end
|
204
|
+
|
205
|
+
def run
|
206
|
+
if @num_registered > 0
|
207
|
+
@running = true
|
208
|
+
EventMachine.run do
|
209
|
+
@registered_procs.each do |proc|
|
210
|
+
perform_request(&proc)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
if @errors.size > 0
|
214
|
+
raise SLFaraday::Error::ClientError, @errors.first || "connection failed"
|
215
|
+
end
|
216
|
+
end
|
217
|
+
ensure
|
218
|
+
reset
|
219
|
+
end
|
220
|
+
|
221
|
+
def perform_request
|
222
|
+
client = yield
|
223
|
+
client.callback { @num_succeeded += 1; check_finished }
|
224
|
+
client.errback { @errors << client.error; check_finished }
|
225
|
+
end
|
226
|
+
|
227
|
+
def check_finished
|
228
|
+
if @num_succeeded + @errors.size == @num_registered
|
229
|
+
EventMachine.stop
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
begin
|
238
|
+
require 'openssl'
|
239
|
+
rescue LoadError
|
240
|
+
warn "Warning: no such file to load -- openssl. Make sure it is installed if you want HTTPS support"
|
241
|
+
else
|
242
|
+
require_relative 'em_http_ssl_patch'
|
243
|
+
end if SLFaraday::Adapter::EMHttp.loaded?
|