arachni-rpc-em 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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