Class: Arachni::RPC::Server
- Defined in:
- lib/arachni/rpc/server.rb,
lib/arachni/rpc/server/handler.rb
Overview
RPC server.
Defined Under Namespace
Classes: Handler
Instance Attribute Summary collapse
- #logger ⇒ Logger readonly
-
#opts ⇒ Hash
readonly
Configuration options.
-
#token ⇒ String
readonly
Authentication token.
Instance Method Summary collapse
- #add_async_check(&block) ⇒ Object
- #add_handler(name, obj) ⇒ Object
- #alive? ⇒ TrueClass
- #call(connection) ⇒ Response
-
#clear_handlers ⇒ Object
Clears all handlers and their associated information like methods and async check blocks.
-
#initialize(opts) ⇒ Server
constructor
Starts the RPC server.
-
#run ⇒ Object
Runs the server and blocks while ‘Arachni::Reactor` is running.
-
#shutdown ⇒ Object
Shuts down the server after 2 seconds.
-
#start ⇒ Object
Starts the server but does not block.
Constructor Details
#initialize(opts) ⇒ Server
Starts the RPC server.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/arachni/rpc/server.rb', line 73 def initialize( opts ) @opts = opts if @opts[:ssl_pkey] && @opts[:ssl_cert] if !File.exist?( @opts[:ssl_pkey] ) raise "Could not find private key at: #{@opts[:ssl_pkey]}" end if !File.exist?( @opts[:ssl_cert] ) raise "Could not find certificate at: #{@opts[:ssl_cert]}" end end @token = @opts[:token] @logger = ::Logger.new( STDOUT ) @logger.level = Logger::INFO @host, @port = @opts[:host], @opts[:port] @socket = @opts[:socket] if !@socket && !(@host || @port) fail ArgumentError, 'Needs either a :socket or :host and :port options.' end @port = @port.to_i @reactor = Reactor.global clear_handlers end |
Instance Attribute Details
#logger ⇒ Logger (readonly)
31 32 33 |
# File 'lib/arachni/rpc/server.rb', line 31 def logger @logger end |
#opts ⇒ Hash (readonly)
Returns Configuration options.
28 29 30 |
# File 'lib/arachni/rpc/server.rb', line 28 def opts @opts end |
#token ⇒ String (readonly)
Returns Authentication token.
24 25 26 |
# File 'lib/arachni/rpc/server.rb', line 24 def token @token end |
Instance Method Details
#add_async_check(&block) ⇒ Object
119 120 121 |
# File 'lib/arachni/rpc/server.rb', line 119 def add_async_check( &block ) @async_checks << block end |
#add_handler(name, obj) ⇒ Object
131 132 133 134 135 136 137 138 139 140 |
# File 'lib/arachni/rpc/server.rb', line 131 def add_handler( name, obj ) @objects[name] = obj @methods[name] = Set.new @async_methods[name] = Set.new obj.class.public_instance_methods( false ).each do |method| @methods[name] << method.to_s @async_methods[name] << method.to_s if async_check( obj.method( method ) ) end end |
#alive? ⇒ TrueClass
219 220 221 |
# File 'lib/arachni/rpc/server.rb', line 219 def alive? true end |
#call(connection) ⇒ Response
If the called method is asynchronous it will be sent by this method directly, otherwise it will be handled by the Handler.
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/arachni/rpc/server.rb', line 179 def call( connection ) req = connection.request peer_ip_addr = connection.peer_address expr, args = req., req.args meth_name, obj_name = parse_expr( expr ) log_call( peer_ip_addr, expr, *args ) if !object_exist?( obj_name ) msg = "Trying to access non-existent object '#{obj_name}'." @logger.error( 'Call' ){ msg + " [on behalf of #{peer_ip_addr}]" } raise Exceptions::InvalidObject.new( msg ) end if !public_method?( obj_name, meth_name ) msg = "Trying to access non-public method '#{meth_name}'." @logger.error( 'Call' ){ msg + " [on behalf of #{peer_ip_addr}]" } raise Exceptions::InvalidMethod.new( msg ) end # The handler needs to know if this is an async call because if it is # we'll have already send the response and it doesn't need to do # transmit anything. res = Response.new res.async! if async?( obj_name, meth_name ) if res.async? @objects[obj_name].send( meth_name.to_sym, *args ) do |obj| res.obj = obj connection.send_response( res ) end else res.obj = @objects[obj_name].send( meth_name.to_sym, *args ) end res end |
#clear_handlers ⇒ Object
Clears all handlers and their associated information like methods and async check blocks.
147 148 149 150 151 152 153 |
# File 'lib/arachni/rpc/server.rb', line 147 def clear_handlers @objects = {} @methods = {} @async_checks = [] @async_methods = {} end |
#run ⇒ Object
Runs the server and blocks while ‘Arachni::Reactor` is running.
156 157 158 |
# File 'lib/arachni/rpc/server.rb', line 156 def run @reactor.run { start } end |
#shutdown ⇒ Object
Shuts down the server after 2 seconds
224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/arachni/rpc/server.rb', line 224 def shutdown wait_for = 2 @logger.info( 'System' ){ "Shutting down in #{wait_for} seconds..." } # Don't die before returning... @reactor.delay( wait_for ) do @reactor.stop end true end |
#start ⇒ Object
Starts the server but does not block.
161 162 163 164 165 166 167 168 169 170 |
# File 'lib/arachni/rpc/server.rb', line 161 def start @logger.info( 'System' ){ 'RPC Server started.' } @logger.info( 'System' ) do interface = @socket ? @socket : "#{@host}:#{@port}" "Listening on #{interface}" end opts = @socket ? @socket : [@host, @port] @reactor.listen( *[opts, Handler, self].flatten ) end |