arachni-rpc-em 0.1.1 → 0.1.2
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.
- data/CHANGELOG.md +6 -0
- data/README.md +3 -11
- data/Rakefile +10 -23
- data/lib/arachni/rpc/em.rb +7 -6
- data/lib/arachni/rpc/em/client.rb +50 -41
- data/lib/arachni/rpc/em/connection_utilities.rb +1 -4
- data/lib/arachni/rpc/em/em.rb +15 -50
- data/lib/arachni/rpc/em/protocol.rb +3 -8
- data/lib/arachni/rpc/em/server.rb +14 -30
- data/lib/arachni/rpc/em/ssl.rb +8 -15
- data/lib/arachni/rpc/em/version.rb +1 -1
- data/spec/arachni/rpc/em/client_spec.rb +39 -58
- data/spec/arachni/rpc/em/server_spec.rb +2 -2
- data/spec/servers/basic.rb +4 -1
- data/spec/servers/server.rb +38 -25
- data/spec/servers/with_ssl_primitives.rb +4 -1
- data/spec/spec_helper.rb +26 -30
- metadata +49 -40
- data/spec/spec.opts +0 -2
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
<table>
|
3
3
|
<tr>
|
4
4
|
<th>Version</th>
|
5
|
-
<td>0.1.
|
5
|
+
<td>0.1.2</td>
|
6
6
|
</tr>
|
7
7
|
<tr>
|
8
8
|
<th>Github page</th>
|
@@ -14,7 +14,7 @@
|
|
14
14
|
</tr>
|
15
15
|
<tr>
|
16
16
|
<th>Author</th>
|
17
|
-
<td><a href="mailto:tasos.laskos@gmail.com">Tasos
|
17
|
+
<td><a href="mailto:tasos.laskos@gmail.com">Tasos "Zapotek" Laskos</a></td>
|
18
18
|
</tr>
|
19
19
|
<tr>
|
20
20
|
<th>Twitter</th>
|
@@ -22,7 +22,7 @@
|
|
22
22
|
</tr>
|
23
23
|
<tr>
|
24
24
|
<th>Copyright</th>
|
25
|
-
<td>2011</td>
|
25
|
+
<td>2011-2012</td>
|
26
26
|
</tr>
|
27
27
|
<tr>
|
28
28
|
<th>License</th>
|
@@ -33,7 +33,6 @@
|
|
33
33
|
## Synopsis
|
34
34
|
|
35
35
|
Arachni-RPC EM is an implementation of the <a href="http://github.com/Arachni/arachni-rpc">Arachni-RPC</a> protocol using EventMachine and provides both a server and a client. <br/>
|
36
|
-
It is under development and will ultimately form the basis for <a href="http://arachni.segfault.gr">Arachni</a>'s Grid infrastructure.
|
37
36
|
|
38
37
|
## Features
|
39
38
|
|
@@ -66,13 +65,6 @@ If you want to clone the repository and work with the source code:
|
|
66
65
|
|
67
66
|
## Running the Specs
|
68
67
|
|
69
|
-
In order to run the specs you must first fire up 2 sample servers like so:
|
70
|
-
|
71
|
-
ruby spec/servers/basic.rb
|
72
|
-
ruby spec/servers/with_ssl_primitives.rb
|
73
|
-
|
74
|
-
Then:
|
75
|
-
|
76
68
|
rake spec
|
77
69
|
|
78
70
|
## Bug reports/Feature requests
|
data/Rakefile
CHANGED
@@ -7,17 +7,21 @@
|
|
7
7
|
=end
|
8
8
|
|
9
9
|
require 'rubygems'
|
10
|
-
require 'rspec'
|
11
|
-
require 'rspec/core/rake_task'
|
12
|
-
|
13
10
|
require File.expand_path( File.dirname( __FILE__ ) ) + '/lib/arachni/rpc/em/version'
|
14
11
|
|
15
|
-
|
16
|
-
|
12
|
+
begin
|
13
|
+
require 'rspec'
|
14
|
+
require 'rspec/core/rake_task'
|
15
|
+
|
16
|
+
RSpec::Core::RakeTask.new
|
17
|
+
rescue LoadError => e
|
18
|
+
puts 'If you want to run the tests please install rspec first:'
|
19
|
+
puts ' gem install rspec'
|
17
20
|
end
|
18
21
|
|
19
|
-
|
22
|
+
task default: [ :spec ]
|
20
23
|
|
24
|
+
desc "Generate docs"
|
21
25
|
task :docs do
|
22
26
|
|
23
27
|
outdir = "../arachni-rpc-pages"
|
@@ -32,39 +36,22 @@ task :docs do
|
|
32
36
|
sh "rm -rf .yard*"
|
33
37
|
end
|
34
38
|
|
35
|
-
|
36
|
-
#
|
37
|
-
# Cleans reports and logs
|
38
|
-
#
|
39
39
|
desc "Cleaning..."
|
40
40
|
task :clean do
|
41
41
|
sh "rm *.gem || true"
|
42
42
|
end
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
#
|
47
|
-
# Building
|
48
|
-
#
|
49
44
|
desc "Build the arachni-rpc-em gem."
|
50
45
|
task :build => [ :clean ] do
|
51
46
|
sh "gem build arachni-rpc-em.gemspec"
|
52
47
|
end
|
53
48
|
|
54
|
-
|
55
|
-
#
|
56
|
-
# Installing
|
57
|
-
#
|
58
49
|
desc "Build and install the arachni gem."
|
59
50
|
task :install => [ :build ] do
|
60
51
|
|
61
52
|
sh "gem install arachni-rpc-em-#{Arachni::RPC::EM::VERSION}.gem"
|
62
53
|
end
|
63
54
|
|
64
|
-
|
65
|
-
#
|
66
|
-
# Publishing
|
67
|
-
#
|
68
55
|
desc "Push a new version to Gemcutter"
|
69
56
|
task :publish => [ :build ] do
|
70
57
|
|
data/lib/arachni/rpc/em.rb
CHANGED
@@ -16,9 +16,10 @@ require 'arachni/rpc'
|
|
16
16
|
require 'yaml'
|
17
17
|
YAML::ENGINE.yamler = 'syck'
|
18
18
|
|
19
|
-
|
20
|
-
require File.join(
|
21
|
-
require File.join(
|
22
|
-
require File.join(
|
23
|
-
require File.join(
|
24
|
-
require File.join(
|
19
|
+
dir = File.expand_path( File.dirname( __FILE__ ) )
|
20
|
+
require File.join( dir, 'em', 'connection_utilities' )
|
21
|
+
require File.join( dir, 'em', 'ssl' )
|
22
|
+
require File.join( dir, 'em', 'protocol' )
|
23
|
+
require File.join( dir, 'em', 'server' )
|
24
|
+
require File.join( dir, 'em', 'client' )
|
25
|
+
require File.join( dir, 'em', 'em' )
|
@@ -19,13 +19,9 @@ module EM
|
|
19
19
|
# - asynchronous and synchronous requests
|
20
20
|
# - handling remote asynchronous calls that require a block
|
21
21
|
#
|
22
|
-
# @author: Tasos "Zapotek" Laskos
|
23
|
-
# <tasos.laskos@gmail.com>
|
24
|
-
# <zapotek@segfault.gr>
|
25
|
-
# @version: 0.1
|
22
|
+
# @author: Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
26
23
|
#
|
27
24
|
class Client
|
28
|
-
|
29
25
|
include ::Arachni::RPC::Exceptions
|
30
26
|
|
31
27
|
#
|
@@ -34,17 +30,20 @@ class Client
|
|
34
30
|
# It's responsible for TLS, storing and calling callbacks as well as
|
35
31
|
# serializing, transmitting and receiving objects.
|
36
32
|
#
|
37
|
-
# @author: Tasos "Zapotek" Laskos
|
38
|
-
# <tasos.laskos@gmail.com>
|
39
|
-
# <zapotek@segfault.gr>
|
40
|
-
# @version: 0.1
|
33
|
+
# @author: Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
41
34
|
#
|
42
35
|
class Handler < EventMachine::Connection
|
43
36
|
include ::Arachni::RPC::EM::Protocol
|
44
37
|
include ::Arachni::RPC::EM::ConnectionUtilities
|
45
38
|
|
39
|
+
DEFAULT_TRIES = 9
|
40
|
+
|
46
41
|
def initialize( opts )
|
47
42
|
@opts = opts
|
43
|
+
@max_retries = @opts[:max_retries] || DEFAULT_TRIES
|
44
|
+
@opts[:tries] ||= 0
|
45
|
+
@tries = @opts[:tries]
|
46
|
+
|
48
47
|
@status = :idle
|
49
48
|
|
50
49
|
@request = nil
|
@@ -59,11 +58,14 @@ class Client
|
|
59
58
|
def unbind( reason )
|
60
59
|
end_ssl
|
61
60
|
|
62
|
-
if @request && @request.callback &&
|
63
|
-
|
64
|
-
|
61
|
+
if @request && @request.callback && status != :done
|
62
|
+
if reason == Errno::ECONNREFUSED && retry?
|
63
|
+
retry_request
|
64
|
+
else
|
65
|
+
e = Arachni::RPC::Exceptions::ConnectionError.new( "Connection closed [#{reason}]" )
|
66
|
+
@request.callback.call( e )
|
67
|
+
end
|
65
68
|
end
|
66
|
-
|
67
69
|
@status = :closed
|
68
70
|
end
|
69
71
|
|
@@ -81,32 +83,43 @@ class Client
|
|
81
83
|
# @param [Arachni::RPC::EM::Response] res
|
82
84
|
#
|
83
85
|
def receive_response( res )
|
86
|
+
@status = :done
|
84
87
|
|
85
88
|
if exception?( res )
|
86
89
|
res.obj = Arachni::RPC::Exceptions.from_response( res )
|
87
90
|
end
|
88
91
|
|
92
|
+
|
89
93
|
if cb = @request.callback
|
90
94
|
|
91
|
-
callback = Proc.new
|
92
|
-
|obj|
|
95
|
+
callback = Proc.new do |obj|
|
93
96
|
cb.call( obj )
|
94
|
-
|
95
|
-
@status = :done
|
96
97
|
close_connection
|
97
|
-
|
98
|
+
end
|
98
99
|
|
99
100
|
if @request.defer?
|
100
101
|
# the callback might block a bit so tell EM to put it in a thread
|
101
|
-
::EM.defer {
|
102
|
-
callback.call( res.obj )
|
103
|
-
}
|
102
|
+
::EM.defer { callback.call( res.obj ) }
|
104
103
|
else
|
105
104
|
callback.call( res.obj )
|
106
105
|
end
|
107
106
|
end
|
108
107
|
end
|
109
108
|
|
109
|
+
def retry_request
|
110
|
+
opts = @opts.dup
|
111
|
+
opts[:tries] += 1
|
112
|
+
EventMachine::Timer.new( 0.1 ){
|
113
|
+
sleep( 0.1 )
|
114
|
+
close_connection
|
115
|
+
::EM.connect( opts[:host], opts[:port], self.class, opts ).send_request( @request )
|
116
|
+
}
|
117
|
+
end
|
118
|
+
|
119
|
+
def retry?
|
120
|
+
@tries < @max_retries
|
121
|
+
end
|
122
|
+
|
110
123
|
# @param [Arachni::RPC::EM::Response] res
|
111
124
|
def exception?( res )
|
112
125
|
res.obj.is_a?( Hash ) && res.obj['exception'] ? true : false
|
@@ -149,6 +162,8 @@ class Client
|
|
149
162
|
# # http://eventmachine.rubyforge.org/EventMachine/Protocols/ObjectProtocol.html#M000369
|
150
163
|
# :serializer => Marshal,
|
151
164
|
#
|
165
|
+
# :max_retries => 0,
|
166
|
+
#
|
152
167
|
# #
|
153
168
|
# # In order to enable peer verification one must first provide
|
154
169
|
# # the following:
|
@@ -164,14 +179,13 @@ class Client
|
|
164
179
|
# @param [Hash] opts
|
165
180
|
#
|
166
181
|
def initialize( opts )
|
167
|
-
|
168
182
|
begin
|
169
|
-
@opts = opts.merge( :
|
183
|
+
@opts = opts.merge( role: :client )
|
170
184
|
@token = @opts[:token]
|
171
185
|
|
172
186
|
@host, @port = @opts[:host], @opts[:port]
|
173
187
|
|
174
|
-
Arachni::RPC::EM.ensure_em_running
|
188
|
+
Arachni::RPC::EM.ensure_em_running
|
175
189
|
rescue EventMachine::ConnectionError => e
|
176
190
|
exc = ConnectionError.new( e.to_s + " for '#{@k}'." )
|
177
191
|
exc.set_backtrace( e.backtrace )
|
@@ -199,22 +213,21 @@ class Client
|
|
199
213
|
# res = server.call( 'handler.method', arg1, arg2 )
|
200
214
|
#
|
201
215
|
# @param [String] msg in the form of <i>handler.method</i>
|
202
|
-
# @param [Array] args collection of
|
216
|
+
# @param [Array] args collection of arguments to be passed to the method
|
203
217
|
# @param [Proc] &block
|
204
218
|
#
|
205
219
|
def call( msg, *args, &block )
|
206
|
-
|
207
220
|
req = Request.new(
|
208
|
-
:
|
209
|
-
:
|
210
|
-
:
|
211
|
-
:
|
221
|
+
message: msg,
|
222
|
+
args: args,
|
223
|
+
callback: block,
|
224
|
+
token: @token
|
212
225
|
)
|
213
226
|
|
214
227
|
if block_given?
|
215
228
|
call_async( req )
|
216
229
|
else
|
217
|
-
|
230
|
+
call_sync( req )
|
218
231
|
end
|
219
232
|
end
|
220
233
|
|
@@ -232,28 +245,24 @@ class Client
|
|
232
245
|
end
|
233
246
|
|
234
247
|
def call_sync( req )
|
235
|
-
|
236
248
|
ret = nil
|
249
|
+
|
237
250
|
# if we're in the Reactor thread use a Fiber and if we're not
|
238
251
|
# use a Thread
|
239
252
|
if !::EM::reactor_thread?
|
240
253
|
t = Thread.current
|
241
|
-
call_async( req )
|
242
|
-
|obj|
|
254
|
+
call_async( req ) do |obj|
|
243
255
|
t.wakeup
|
244
256
|
ret = obj
|
245
|
-
|
257
|
+
end
|
246
258
|
sleep
|
247
259
|
else
|
248
260
|
# Fibers do not work across threads so don't defer the callback
|
249
261
|
# once the Handler gets to it
|
250
|
-
req.do_not_defer
|
262
|
+
req.do_not_defer
|
251
263
|
|
252
264
|
f = Fiber.current
|
253
|
-
call_async( req ) {
|
254
|
-
|obj|
|
255
|
-
f.resume( obj )
|
256
|
-
}
|
265
|
+
call_async( req ) { |obj| f.resume( obj ) }
|
257
266
|
|
258
267
|
begin
|
259
268
|
ret = Fiber.yield
|
@@ -268,7 +277,7 @@ class Client
|
|
268
277
|
end
|
269
278
|
|
270
279
|
raise ret if ret.is_a?( Exception )
|
271
|
-
|
280
|
+
ret
|
272
281
|
end
|
273
282
|
|
274
283
|
end
|
@@ -13,10 +13,7 @@ module EM
|
|
13
13
|
#
|
14
14
|
# Helper methods to be included in EventMachine::Connection classes
|
15
15
|
#
|
16
|
-
# @author: Tasos "Zapotek" Laskos
|
17
|
-
# <tasos.laskos@gmail.com>
|
18
|
-
# <zapotek@segfault.gr>
|
19
|
-
# @version: 0.1
|
16
|
+
# @author: Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
20
17
|
#
|
21
18
|
module ConnectionUtilities
|
22
19
|
|
data/lib/arachni/rpc/em/em.rb
CHANGED
@@ -12,59 +12,32 @@ module RPC
|
|
12
12
|
#
|
13
13
|
# Provides some convenient methods for EventMachine's Reactor.
|
14
14
|
#
|
15
|
-
# @author: Tasos "Zapotek" Laskos
|
16
|
-
# <tasos.laskos@gmail.com>
|
17
|
-
# <zapotek@segfault.gr>
|
18
|
-
# @version: 0.1
|
15
|
+
# @author: Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
19
16
|
#
|
20
17
|
module EM
|
21
18
|
|
22
|
-
module Synchrony
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
block.call
|
27
|
-
}.resume
|
28
|
-
end
|
29
|
-
|
30
|
-
extend self
|
31
|
-
|
32
|
-
end
|
19
|
+
module Synchrony
|
20
|
+
def run( &block )
|
21
|
+
Fiber.new{ block.call }.resume
|
22
|
+
end
|
33
23
|
|
34
|
-
|
35
|
-
# Inits method variables for the Reactor tasks and its Mutex.
|
36
|
-
#
|
37
|
-
def init
|
38
|
-
@@reactor_tasks_mutex ||= Mutex.new
|
39
|
-
@@reactor_tasks ||= []
|
24
|
+
extend self
|
40
25
|
end
|
41
26
|
|
42
27
|
#
|
43
|
-
#
|
28
|
+
# Schedules a block to be run in the EM reactor.
|
44
29
|
#
|
45
|
-
# @param [Proc] &block
|
30
|
+
# @param [Proc] &block
|
46
31
|
#
|
47
|
-
def
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
# if we're already in the Reactor thread just run the block straight up.
|
52
|
-
if ::EM::reactor_thread?
|
53
|
-
block.call
|
54
|
-
else
|
55
|
-
@@reactor_tasks_mutex.lock
|
56
|
-
@@reactor_tasks << block
|
57
|
-
|
58
|
-
ensure_em_running!
|
59
|
-
@@reactor_tasks_mutex.unlock
|
60
|
-
end
|
61
|
-
|
32
|
+
def schedule( &block )
|
33
|
+
ensure_em_running
|
34
|
+
::EM.schedule( &block )
|
62
35
|
end
|
63
36
|
|
64
37
|
#
|
65
38
|
# Blocks until the Reactor stops running
|
66
39
|
#
|
67
|
-
def block
|
40
|
+
def block
|
68
41
|
# beware of deadlocks, we can't join our own thread
|
69
42
|
::EM.reactor_thread.join if ::EM.reactor_thread && !::EM::reactor_thread?
|
70
43
|
end
|
@@ -72,28 +45,20 @@ end
|
|
72
45
|
#
|
73
46
|
# Puts the Reactor in its own thread and runs it.
|
74
47
|
#
|
75
|
-
|
76
|
-
#
|
77
|
-
def ensure_em_running!
|
78
|
-
self.init
|
79
|
-
|
48
|
+
def ensure_em_running
|
80
49
|
if !::EM::reactor_running?
|
81
|
-
q = Queue.new
|
82
50
|
|
83
51
|
Thread.new do
|
84
52
|
::EM::run do
|
85
|
-
|
86
53
|
::EM.error_handler do |e|
|
87
54
|
$stderr.puts "Exception raised during event loop: " +
|
88
55
|
"#{e.message} (#{e.class})\n#{(e.backtrace ||
|
89
56
|
[])[0..5].join("\n")}"
|
90
57
|
end
|
91
|
-
|
92
|
-
@@reactor_tasks.each { |task| task.call }
|
93
|
-
q << true
|
94
58
|
end
|
95
59
|
end
|
96
|
-
|
60
|
+
|
61
|
+
sleep 0.1 while !::EM.reactor_running?
|
97
62
|
end
|
98
63
|
end
|
99
64
|
|
@@ -13,10 +13,7 @@ module EM
|
|
13
13
|
#
|
14
14
|
# Provides helper transport methods for {Message} transmission.
|
15
15
|
#
|
16
|
-
# @author: Tasos "Zapotek" Laskos
|
17
|
-
# <tasos.laskos@gmail.com>
|
18
|
-
# <zapotek@segfault.gr>
|
19
|
-
# @version: 0.1
|
16
|
+
# @author: Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
20
17
|
#
|
21
18
|
module Protocol
|
22
19
|
include ::Arachni::RPC::EM::SSL
|
@@ -73,9 +70,7 @@ module Protocol
|
|
73
70
|
# @param [Arachni::RPC::EM::Message] msg
|
74
71
|
#
|
75
72
|
def send_message( msg )
|
76
|
-
::EM.schedule {
|
77
|
-
send_object( msg.prepare_for_tx )
|
78
|
-
}
|
73
|
+
::EM.schedule { send_object( msg.prepare_for_tx ) }
|
79
74
|
end
|
80
75
|
alias :send_request :send_message
|
81
76
|
alias :send_response :send_message
|
@@ -128,7 +123,7 @@ module Protocol
|
|
128
123
|
data = serializer.dump( obj )
|
129
124
|
packed = [data.bytesize, data].pack( 'Na*' )
|
130
125
|
|
131
|
-
while
|
126
|
+
while packed
|
132
127
|
if packed.bytesize > MAX_CHUNK_SIZE
|
133
128
|
send_data( packed.slice!( 0, MAX_CHUNK_SIZE ) )
|
134
129
|
else
|
@@ -19,13 +19,9 @@ module EM
|
|
19
19
|
# - asynchronous and synchronous requests
|
20
20
|
# - handling asynchronous methods that require a block
|
21
21
|
#
|
22
|
-
# @author: Tasos "Zapotek" Laskos
|
23
|
-
# <tasos.laskos@gmail.com>
|
24
|
-
# <zapotek@segfault.gr>
|
25
|
-
# @version: 0.1
|
22
|
+
# @author: Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
26
23
|
#
|
27
24
|
class Server
|
28
|
-
|
29
25
|
include ::Arachni::RPC::Exceptions
|
30
26
|
|
31
27
|
#
|
@@ -36,13 +32,9 @@ class Server
|
|
36
32
|
#
|
37
33
|
# It also handles and forwards exceptions.
|
38
34
|
#
|
39
|
-
# @author: Tasos "Zapotek" Laskos
|
40
|
-
# <tasos.laskos@gmail.com>
|
41
|
-
# <zapotek@segfault.gr>
|
42
|
-
# @version: 0.1
|
35
|
+
# @author: Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
43
36
|
#
|
44
37
|
class Proxy < EventMachine::Connection
|
45
|
-
|
46
38
|
include ::Arachni::RPC::EM::Protocol
|
47
39
|
include ::Arachni::RPC::Exceptions
|
48
40
|
include ::Arachni::RPC::EM::ConnectionUtilities
|
@@ -156,7 +148,7 @@ class Server
|
|
156
148
|
msg + " [on behalf of #{peer_ip_addr}]"
|
157
149
|
}
|
158
150
|
|
159
|
-
raise
|
151
|
+
raise InvalidToken.new( msg )
|
160
152
|
end
|
161
153
|
end
|
162
154
|
|
@@ -269,11 +261,10 @@ class Server
|
|
269
261
|
@methods[name] = Set.new # no lookup overhead please :)
|
270
262
|
@async_methods[name] = Set.new
|
271
263
|
|
272
|
-
obj.class.public_instance_methods( false ).each
|
273
|
-
|method|
|
264
|
+
obj.class.public_instance_methods( false ).each do |method|
|
274
265
|
@methods[name] << method.to_s
|
275
266
|
@async_methods[name] << method.to_s if async_check( obj.method( method ) )
|
276
|
-
|
267
|
+
end
|
277
268
|
end
|
278
269
|
|
279
270
|
#
|
@@ -292,10 +283,8 @@ class Server
|
|
292
283
|
# Runs the server and blocks.
|
293
284
|
#
|
294
285
|
def run
|
295
|
-
Arachni::RPC::EM.
|
296
|
-
|
297
|
-
}
|
298
|
-
Arachni::RPC::EM.block!
|
286
|
+
Arachni::RPC::EM.schedule { start }
|
287
|
+
Arachni::RPC::EM.block
|
299
288
|
end
|
300
289
|
|
301
290
|
#
|
@@ -338,21 +327,20 @@ class Server
|
|
338
327
|
if !res.async?
|
339
328
|
res.obj = @objects[obj_name].send( meth_name.to_sym, *args )
|
340
329
|
else
|
341
|
-
@objects[obj_name].send( meth_name.to_sym, *args )
|
342
|
-
|obj|
|
330
|
+
@objects[obj_name].send( meth_name.to_sym, *args ) do |obj|
|
343
331
|
res.obj = obj
|
344
332
|
connection.send_response( res )
|
345
|
-
|
333
|
+
end
|
346
334
|
end
|
347
335
|
|
348
|
-
|
336
|
+
res
|
349
337
|
end
|
350
338
|
|
351
339
|
#
|
352
340
|
# @return [TrueClass]
|
353
341
|
#
|
354
342
|
def alive?
|
355
|
-
|
343
|
+
true
|
356
344
|
end
|
357
345
|
|
358
346
|
#
|
@@ -365,7 +353,7 @@ class Server
|
|
365
353
|
|
366
354
|
# don't die before returning
|
367
355
|
EventMachine::add_timer( wait_for ) { ::EM.stop }
|
368
|
-
|
356
|
+
true
|
369
357
|
end
|
370
358
|
|
371
359
|
private
|
@@ -375,11 +363,8 @@ class Server
|
|
375
363
|
end
|
376
364
|
|
377
365
|
def async_check( method )
|
378
|
-
@async_checks.each {
|
379
|
-
|
380
|
-
return true if check.call( method )
|
381
|
-
}
|
382
|
-
return false
|
366
|
+
@async_checks.each { |check| return true if check.call( method ) }
|
367
|
+
false
|
383
368
|
end
|
384
369
|
|
385
370
|
|
@@ -399,7 +384,6 @@ class Server
|
|
399
384
|
|
400
385
|
def parse_expr( expr )
|
401
386
|
parts = expr.to_s.split( '.' )
|
402
|
-
|
403
387
|
# method name, object name
|
404
388
|
[ parts.pop, parts.join( '.' ) ]
|
405
389
|
end
|
data/lib/arachni/rpc/em/ssl.rb
CHANGED
@@ -40,13 +40,9 @@ module EM
|
|
40
40
|
#
|
41
41
|
# @see https://gist.github.com/1151454
|
42
42
|
#
|
43
|
-
# @author: Tasos "Zapotek" Laskos
|
44
|
-
# <tasos.laskos@gmail.com>
|
45
|
-
# <zapotek@segfault.gr>
|
46
|
-
# @version: 0.1
|
43
|
+
# @author: Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
47
44
|
#
|
48
45
|
module SSL
|
49
|
-
|
50
46
|
include ::Arachni::RPC::EM::ConnectionUtilities
|
51
47
|
|
52
48
|
#
|
@@ -58,13 +54,11 @@ module SSL
|
|
58
54
|
|
59
55
|
ssl_opts = {}
|
60
56
|
if ssl_opts?
|
61
|
-
|
62
57
|
ssl_opts = {
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
58
|
+
private_key_file: @opts[:ssl_pkey],
|
59
|
+
cert_chain_file: @opts[:ssl_cert],
|
60
|
+
verify_peer: true
|
61
|
+
}
|
68
62
|
@last_seen_cert = nil
|
69
63
|
end
|
70
64
|
|
@@ -110,7 +104,7 @@ module SSL
|
|
110
104
|
end
|
111
105
|
end
|
112
106
|
|
113
|
-
|
107
|
+
@ca_store
|
114
108
|
end
|
115
109
|
|
116
110
|
#
|
@@ -119,7 +113,6 @@ module SSL
|
|
119
113
|
# @see http://eventmachine.rubyforge.org/EventMachine/Connection.html#M000271
|
120
114
|
#
|
121
115
|
def ssl_verify_peer( cert_string )
|
122
|
-
|
123
116
|
cert = OpenSSL::X509::Certificate.new( cert_string )
|
124
117
|
|
125
118
|
# Some servers send the same certificate multiple times. I'm not even
|
@@ -134,12 +127,12 @@ module SSL
|
|
134
127
|
ca_store.add_cert( @last_seen_cert ) if !@last_seen_cert.root?
|
135
128
|
|
136
129
|
@verified_peer = true
|
137
|
-
|
130
|
+
true
|
138
131
|
else
|
139
132
|
log( :error, 'SSL',
|
140
133
|
"#{ca_store.error_string.capitalize} ['#{peer_ip_addr}']."
|
141
134
|
)
|
142
|
-
|
135
|
+
false
|
143
136
|
end
|
144
137
|
end
|
145
138
|
|
@@ -3,11 +3,8 @@ require File.join( File.expand_path( File.dirname( __FILE__ ) ), '../../../', 's
|
|
3
3
|
describe Arachni::RPC::EM::Client do
|
4
4
|
|
5
5
|
before( :all ) do
|
6
|
-
@arg = [
|
7
|
-
|
8
|
-
2,
|
9
|
-
{ :three => 3 },
|
10
|
-
[ 4 ]
|
6
|
+
@arg = [ 'one', 2,
|
7
|
+
{ :three => 3 }, [ 4 ]
|
11
8
|
]
|
12
9
|
end
|
13
10
|
|
@@ -27,37 +24,32 @@ describe Arachni::RPC::EM::Client do
|
|
27
24
|
end
|
28
25
|
|
29
26
|
it "should be able to perform asynchronous calls" do
|
30
|
-
start_client( rpc_opts ).call( 'test.foo', @arg )
|
31
|
-
|res|
|
27
|
+
start_client( rpc_opts ).call( 'test.foo', @arg ) do |res|
|
32
28
|
@arg.should == res
|
33
29
|
::EM.stop
|
34
|
-
|
35
|
-
Arachni::RPC::EM.block
|
30
|
+
end
|
31
|
+
Arachni::RPC::EM.block
|
36
32
|
end
|
37
33
|
end
|
38
34
|
|
39
35
|
context "when run inside the Reactor loop" do
|
40
36
|
|
41
37
|
it "should be able to perform synchronous calls" do
|
42
|
-
::EM.run
|
43
|
-
|
38
|
+
::EM.run {
|
44
39
|
::Arachni::RPC::EM::Synchrony.run do
|
45
40
|
@arg.should == start_client( rpc_opts ).call( 'test.foo', @arg )
|
46
41
|
::EM.stop
|
47
42
|
end
|
48
|
-
|
43
|
+
}
|
49
44
|
end
|
50
45
|
|
51
46
|
it "should be able to perform asynchronous calls" do
|
52
|
-
::EM.run
|
53
|
-
|
54
|
-
start_client( rpc_opts ).call( 'test.foo', @arg ) {
|
55
|
-
|res|
|
47
|
+
::EM.run {
|
48
|
+
start_client( rpc_opts ).call( 'test.foo', @arg ) do |res|
|
56
49
|
res.should == @arg
|
57
50
|
::EM.stop
|
58
|
-
|
59
|
-
|
60
|
-
end
|
51
|
+
end
|
52
|
+
}
|
61
53
|
end
|
62
54
|
|
63
55
|
end
|
@@ -72,12 +64,11 @@ describe Arachni::RPC::EM::Client do
|
|
72
64
|
|
73
65
|
it "should be able to properly forward synchronous calls" do
|
74
66
|
test = Arachni::RPC::RemoteObjectMapper.new( start_client( rpc_opts ), 'test' )
|
75
|
-
test.foo( @arg )
|
76
|
-
|res|
|
67
|
+
test.foo( @arg ) do |res|
|
77
68
|
res.should == @arg
|
78
69
|
::EM.stop
|
79
|
-
|
80
|
-
Arachni::RPC::EM.block
|
70
|
+
end
|
71
|
+
Arachni::RPC::EM.block
|
81
72
|
end
|
82
73
|
end
|
83
74
|
|
@@ -85,30 +76,27 @@ describe Arachni::RPC::EM::Client do
|
|
85
76
|
context 'when performing asynchronous calls' do
|
86
77
|
|
87
78
|
it "should be returned when requesting inexistent objects" do
|
88
|
-
start_client( rpc_opts ).call( 'bar.foo' )
|
89
|
-
|res|
|
79
|
+
start_client( rpc_opts ).call( 'bar.foo' ) do |res|
|
90
80
|
res.rpc_invalid_object_error?.should be_true
|
91
81
|
::EM.stop
|
92
|
-
|
93
|
-
Arachni::RPC::EM.block
|
82
|
+
end
|
83
|
+
Arachni::RPC::EM.block
|
94
84
|
end
|
95
85
|
|
96
86
|
it "should be returned when requesting inexistent or non-public methods" do
|
97
|
-
start_client( rpc_opts ).call( 'test.bar' )
|
98
|
-
|res|
|
87
|
+
start_client( rpc_opts ).call( 'test.bar' ) do |res|
|
99
88
|
res.rpc_invalid_method_error?.should be_true
|
100
89
|
::EM.stop
|
101
|
-
|
102
|
-
Arachni::RPC::EM.block
|
90
|
+
end
|
91
|
+
Arachni::RPC::EM.block
|
103
92
|
end
|
104
93
|
|
105
94
|
it "should be returned when there's a remote exception" do
|
106
|
-
start_client( rpc_opts ).call( 'test.foo' )
|
107
|
-
|res|
|
95
|
+
start_client( rpc_opts ).call( 'test.foo' ) do |res|
|
108
96
|
res.rpc_remote_exception?.should be_true
|
109
97
|
::EM.stop
|
110
|
-
|
111
|
-
Arachni::RPC::EM.block
|
98
|
+
end
|
99
|
+
Arachni::RPC::EM.block
|
112
100
|
end
|
113
101
|
|
114
102
|
end
|
@@ -146,35 +134,30 @@ describe Arachni::RPC::EM::Client do
|
|
146
134
|
it "should be able to retain stability and consistency under heavy load" do
|
147
135
|
client = start_client( rpc_opts )
|
148
136
|
|
149
|
-
n =
|
137
|
+
n = 400
|
150
138
|
cnt = 0
|
151
139
|
|
152
140
|
mismatches = []
|
153
141
|
|
154
|
-
n.times
|
155
|
-
|
156
|
-
client.call( 'test.foo', i ) {
|
157
|
-
|res|
|
158
|
-
|
142
|
+
n.times do |i|
|
143
|
+
client.call( 'test.foo', i ) do |res|
|
159
144
|
cnt += 1
|
160
|
-
|
161
145
|
mismatches << [i, res] if i != res
|
162
146
|
::EM.stop if cnt == n || !mismatches.empty?
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
Arachni::RPC::EM.block!
|
147
|
+
end
|
148
|
+
end
|
167
149
|
|
150
|
+
Arachni::RPC::EM.block
|
151
|
+
cnt.should > 0
|
168
152
|
mismatches.should be_empty
|
169
153
|
end
|
170
154
|
|
171
155
|
it "should throw error when connecting to inexistent server" do
|
172
|
-
start_client( rpc_opts.merge( :port => 9999 ) ).call( 'test.foo', @arg )
|
173
|
-
|res|
|
156
|
+
start_client( rpc_opts.merge( :port => 9999 ) ).call( 'test.foo', @arg ) do |res|
|
174
157
|
res.rpc_connection_error?.should be_true
|
175
158
|
::EM.stop
|
176
|
-
|
177
|
-
Arachni::RPC::EM.block
|
159
|
+
end
|
160
|
+
Arachni::RPC::EM.block
|
178
161
|
end
|
179
162
|
|
180
163
|
context "when using valid SSL primitives" do
|
@@ -187,24 +170,22 @@ describe Arachni::RPC::EM::Client do
|
|
187
170
|
|
188
171
|
context "when using invalid SSL primitives" do
|
189
172
|
it "should not be able to establish a connection" do
|
190
|
-
start_client( rpc_opts_with_invalid_ssl_primitives ).call( 'test.foo', @arg )
|
191
|
-
|res|
|
173
|
+
start_client( rpc_opts_with_invalid_ssl_primitives ).call( 'test.foo', @arg ) do |res|
|
192
174
|
res.rpc_connection_error?.should be_true
|
193
175
|
::EM.stop
|
194
|
-
|
195
|
-
Arachni::RPC::EM.block
|
176
|
+
end
|
177
|
+
Arachni::RPC::EM.block
|
196
178
|
end
|
197
179
|
end
|
198
180
|
|
199
181
|
context "when using mixed SSL primitives" do
|
200
182
|
it "should not be able to establish a connection" do
|
201
|
-
start_client( rpc_opts_with_mixed_ssl_primitives ).call( 'test.foo', @arg )
|
202
|
-
|res|
|
183
|
+
start_client( rpc_opts_with_mixed_ssl_primitives ).call( 'test.foo', @arg ) do |res|
|
203
184
|
res.rpc_connection_error?.should be_true
|
204
185
|
res.rpc_ssl_error?.should be_true
|
205
186
|
::EM.stop
|
206
|
-
|
207
|
-
Arachni::RPC::EM.block
|
187
|
+
end
|
188
|
+
Arachni::RPC::EM.block
|
208
189
|
end
|
209
190
|
end
|
210
191
|
|
@@ -8,8 +8,8 @@ end
|
|
8
8
|
describe Arachni::RPC::EM::Server do
|
9
9
|
|
10
10
|
before( :all ) do
|
11
|
-
@opts = rpc_opts.merge( :
|
12
|
-
@server
|
11
|
+
@opts = rpc_opts.merge( port: 7333 )
|
12
|
+
@server = start_server( @opts, true )
|
13
13
|
end
|
14
14
|
|
15
15
|
describe "#initialize" do
|
data/spec/servers/basic.rb
CHANGED
data/spec/servers/server.rb
CHANGED
@@ -10,11 +10,42 @@
|
|
10
10
|
|
11
11
|
$cwd = cwd = File.expand_path( File.dirname( __FILE__ ) )
|
12
12
|
require File.join( cwd, '../../lib/arachni/rpc/', 'em' )
|
13
|
-
|
13
|
+
|
14
|
+
def rpc_opts
|
15
|
+
{
|
16
|
+
host: 'localhost',
|
17
|
+
port: 7331,
|
18
|
+
token: 'superdupersecret',
|
19
|
+
serializer: Marshal,
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def rpc_opts_with_ssl_primitives
|
24
|
+
rpc_opts.merge(
|
25
|
+
port: 7332,
|
26
|
+
ssl_ca: cwd + '/pems/cacert.pem',
|
27
|
+
ssl_pkey: cwd + '/pems/client/key.pem',
|
28
|
+
ssl_cert: cwd + '/pems/client/cert.pem'
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def rpc_opts_with_invalid_ssl_primitives
|
33
|
+
rpc_opts_with_ssl_primitives.merge(
|
34
|
+
ssl_pkey: cwd + '/pems/client/foo-key.pem',
|
35
|
+
ssl_cert: cwd + '/pems/client/foo-cert.pem'
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
def rpc_opts_with_mixed_ssl_primitives
|
40
|
+
rpc_opts_with_ssl_primitives.merge(
|
41
|
+
ssl_pkey: cwd + '/pems/client/key.pem',
|
42
|
+
ssl_cert: cwd + '/pems/client/foo-cert.pem'
|
43
|
+
)
|
44
|
+
end
|
14
45
|
|
15
46
|
class Parent
|
16
47
|
def foo( arg )
|
17
|
-
|
48
|
+
arg
|
18
49
|
end
|
19
50
|
end
|
20
51
|
|
@@ -23,39 +54,21 @@ class Test < Parent
|
|
23
54
|
# in order to make inherited methods accessible you've got to explicitly
|
24
55
|
# make them public
|
25
56
|
private :foo
|
26
|
-
public
|
57
|
+
public :foo
|
27
58
|
|
28
59
|
#
|
29
60
|
# Uses EventMachine to call the block asynchronously
|
30
61
|
#
|
31
62
|
def async_foo( arg, &block )
|
32
|
-
::EM.schedule {
|
33
|
-
::EM.defer {
|
34
|
-
block.call( arg ) if block_given?
|
35
|
-
}
|
36
|
-
}
|
63
|
+
::EM.schedule { ::EM.defer { block.call( arg ) if block_given? } }
|
37
64
|
end
|
38
65
|
|
39
66
|
end
|
40
67
|
|
41
68
|
def start_server( opts, do_not_start = false )
|
42
|
-
|
43
69
|
server = Arachni::RPC::EM::Server.new( opts )
|
44
|
-
|
45
|
-
server.add_async_check {
|
46
|
-
|method|
|
47
|
-
#
|
48
|
-
# Must return 'true' for async and 'false' for sync.
|
49
|
-
#
|
50
|
-
# Very simple check here...
|
51
|
-
#
|
52
|
-
'async' == method.name.to_s.split( '_' )[0]
|
53
|
-
}
|
54
|
-
|
70
|
+
server.add_async_check { |method| method.name.to_s.start_with?( 'async_' ) }
|
55
71
|
server.add_handler( 'test', Test.new )
|
56
|
-
|
57
|
-
|
58
|
-
t = Thread.new { server.run } if !do_not_start
|
59
|
-
|
60
|
-
return server, t
|
72
|
+
server.run if !do_not_start
|
73
|
+
server
|
61
74
|
end
|
@@ -1,5 +1,8 @@
|
|
1
1
|
require_relative 'server'
|
2
2
|
|
3
|
+
$stdout.reopen( '/dev/null', 'w' )
|
4
|
+
$stderr.reopen( '/dev/null', 'w' )
|
5
|
+
|
3
6
|
cwd = File.expand_path( File.dirname( __FILE__ ) )
|
4
7
|
opts = rpc_opts.merge(
|
5
8
|
:port => 7332,
|
@@ -8,4 +11,4 @@ opts = rpc_opts.merge(
|
|
8
11
|
:ssl_cert => cwd + '/../pems/server/cert.pem'
|
9
12
|
)
|
10
13
|
|
11
|
-
start_server( opts )
|
14
|
+
start_server( opts )
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require 'rspec'
|
2
2
|
require 'timeout'
|
3
3
|
|
4
4
|
def cwd
|
@@ -8,39 +8,35 @@ end
|
|
8
8
|
require File.join( cwd, '../lib/arachni/rpc/', 'em' )
|
9
9
|
require File.join( cwd, 'servers', 'server' )
|
10
10
|
|
11
|
-
def
|
12
|
-
|
13
|
-
:host => 'localhost',
|
14
|
-
:port => 7331,
|
15
|
-
:token => 'superdupersecret',
|
16
|
-
:serializer => Marshal,
|
17
|
-
}
|
18
|
-
end
|
19
|
-
|
20
|
-
def rpc_opts_with_ssl_primitives
|
21
|
-
rpc_opts.merge(
|
22
|
-
:port => 7332,
|
23
|
-
:ssl_ca => cwd + '/pems/cacert.pem',
|
24
|
-
:ssl_pkey => cwd + '/pems/client/key.pem',
|
25
|
-
:ssl_cert => cwd + '/pems/client/cert.pem'
|
26
|
-
)
|
11
|
+
def start_client( opts )
|
12
|
+
Arachni::RPC::EM::Client.new( opts )
|
27
13
|
end
|
28
14
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
15
|
+
def quiet_fork( &block )
|
16
|
+
fork {
|
17
|
+
$stdout.reopen( '/dev/null', 'w' )
|
18
|
+
$stderr.reopen( '/dev/null', 'w' )
|
19
|
+
block.call
|
20
|
+
}
|
34
21
|
end
|
35
22
|
|
36
|
-
def
|
37
|
-
|
38
|
-
:ssl_pkey => cwd + '/pems/client/key.pem',
|
39
|
-
:ssl_cert => cwd + '/pems/client/foo-cert.pem'
|
40
|
-
)
|
23
|
+
def quiet_spawn( file )
|
24
|
+
Process.spawn 'ruby ' + file
|
41
25
|
end
|
42
26
|
|
43
|
-
|
44
|
-
|
45
|
-
|
27
|
+
server_pids = []
|
28
|
+
RSpec.configure do |config|
|
29
|
+
config.color = true
|
30
|
+
config.add_formatter :documentation
|
31
|
+
|
32
|
+
config.before( :suite ) do
|
33
|
+
server_pids << quiet_spawn( File.join( cwd, 'servers', 'basic.rb' ) )
|
34
|
+
server_pids << quiet_spawn( File.join( cwd, 'servers', 'with_ssl_primitives.rb' ) )
|
35
|
+
server_pids.each { |pid| Process.detach( pid ) }
|
36
|
+
sleep 2
|
37
|
+
end
|
38
|
+
|
39
|
+
config.after( :suite ) do
|
40
|
+
server_pids.each { |pid| Process.kill( 'KILL', pid ) }
|
41
|
+
end
|
46
42
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arachni-rpc-em
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-08-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: eventmachine
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: 1.0.0.beta.4
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.0.0.beta.4
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: em-synchrony
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,18 +37,28 @@ dependencies:
|
|
32
37
|
version: 1.0.0
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.0.0
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: arachni-rpc
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
|
-
- - =
|
51
|
+
- - '='
|
42
52
|
- !ruby/object:Gem::Version
|
43
|
-
version: 0.1.
|
53
|
+
version: 0.1.2
|
44
54
|
type: :runtime
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.1.2
|
47
62
|
description: ! " EventMachine-based client and server implementation of Arachni-RPC
|
48
63
|
supporting\n TLS encryption, asynchronous and synchronous requests and\n
|
49
64
|
\ capable of handling remote asynchronous calls that require a block.\n"
|
@@ -59,33 +74,32 @@ files:
|
|
59
74
|
- Rakefile
|
60
75
|
- LICENSE.md
|
61
76
|
- CHANGELOG.md
|
62
|
-
- lib/arachni/rpc/em.rb
|
63
|
-
- lib/arachni/rpc/em/protocol.rb
|
64
|
-
- lib/arachni/rpc/em/ssl.rb
|
65
77
|
- lib/arachni/rpc/em/version.rb
|
66
|
-
- lib/arachni/rpc/em/connection_utilities.rb
|
67
78
|
- lib/arachni/rpc/em/em.rb
|
68
79
|
- lib/arachni/rpc/em/client.rb
|
69
80
|
- lib/arachni/rpc/em/server.rb
|
81
|
+
- lib/arachni/rpc/em/protocol.rb
|
82
|
+
- lib/arachni/rpc/em/connection_utilities.rb
|
83
|
+
- lib/arachni/rpc/em/ssl.rb
|
84
|
+
- lib/arachni/rpc/em.rb
|
85
|
+
- examples/client.EM.run.rb
|
70
86
|
- examples/client.rb
|
71
87
|
- examples/server.rb
|
72
|
-
- examples/client.EM.run.rb
|
73
|
-
- spec/servers/with_ssl_primitives.rb
|
74
|
-
- spec/servers/basic.rb
|
75
|
-
- spec/servers/server.rb
|
76
|
-
- spec/spec_helper.rb
|
77
|
-
- spec/arachni/rpc/em/server_spec.rb
|
78
|
-
- spec/arachni/rpc/em/ssl_spec.rb
|
79
|
-
- spec/arachni/rpc/em/em_spec.rb
|
80
|
-
- spec/arachni/rpc/em/client_spec.rb
|
81
88
|
- spec/pems/cacert.pem
|
82
89
|
- spec/pems/server/key.pem
|
83
90
|
- spec/pems/server/cert.pem
|
84
|
-
- spec/pems/client/key.pem
|
85
91
|
- spec/pems/client/foo-cert.pem
|
86
92
|
- spec/pems/client/foo-key.pem
|
93
|
+
- spec/pems/client/key.pem
|
87
94
|
- spec/pems/client/cert.pem
|
88
|
-
- spec/
|
95
|
+
- spec/arachni/rpc/em/em_spec.rb
|
96
|
+
- spec/arachni/rpc/em/server_spec.rb
|
97
|
+
- spec/arachni/rpc/em/client_spec.rb
|
98
|
+
- spec/arachni/rpc/em/ssl_spec.rb
|
99
|
+
- spec/spec_helper.rb
|
100
|
+
- spec/servers/server.rb
|
101
|
+
- spec/servers/basic.rb
|
102
|
+
- spec/servers/with_ssl_primitives.rb
|
89
103
|
homepage: https://github.com/Arachni/arachni-rpc
|
90
104
|
licenses: []
|
91
105
|
post_install_message:
|
@@ -107,28 +121,23 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
107
121
|
version: '0'
|
108
122
|
requirements: []
|
109
123
|
rubyforge_project:
|
110
|
-
rubygems_version: 1.8.
|
124
|
+
rubygems_version: 1.8.24
|
111
125
|
signing_key:
|
112
126
|
specification_version: 3
|
113
127
|
summary: The RPC client and server used by the Arachni WebAppSec scanner Grid.
|
114
128
|
test_files:
|
115
|
-
- examples/client.rb
|
116
|
-
- examples/server.rb
|
117
|
-
- examples/client.EM.run.rb
|
118
|
-
- spec/servers/with_ssl_primitives.rb
|
119
|
-
- spec/servers/basic.rb
|
120
|
-
- spec/servers/server.rb
|
121
|
-
- spec/spec_helper.rb
|
122
|
-
- spec/arachni/rpc/em/server_spec.rb
|
123
|
-
- spec/arachni/rpc/em/ssl_spec.rb
|
124
|
-
- spec/arachni/rpc/em/em_spec.rb
|
125
|
-
- spec/arachni/rpc/em/client_spec.rb
|
126
129
|
- spec/pems/cacert.pem
|
127
130
|
- spec/pems/server/key.pem
|
128
131
|
- spec/pems/server/cert.pem
|
129
|
-
- spec/pems/client/key.pem
|
130
132
|
- spec/pems/client/foo-cert.pem
|
131
133
|
- spec/pems/client/foo-key.pem
|
134
|
+
- spec/pems/client/key.pem
|
132
135
|
- spec/pems/client/cert.pem
|
133
|
-
- spec/
|
134
|
-
|
136
|
+
- spec/arachni/rpc/em/em_spec.rb
|
137
|
+
- spec/arachni/rpc/em/server_spec.rb
|
138
|
+
- spec/arachni/rpc/em/client_spec.rb
|
139
|
+
- spec/arachni/rpc/em/ssl_spec.rb
|
140
|
+
- spec/spec_helper.rb
|
141
|
+
- spec/servers/server.rb
|
142
|
+
- spec/servers/basic.rb
|
143
|
+
- spec/servers/with_ssl_primitives.rb
|
data/spec/spec.opts
DELETED