Class: Arachni::RPC::Client::Handler

Inherits:
Reactor::Connection
  • Object
show all
Includes:
Protocol
Defined in:
lib/arachni/rpc/client/handler.rb

Overview

Transmits Request objects and calls callbacks once an Response is received.

Author:

Constant Summary collapse

DEFAULT_TRIES =

Default amount of tries for failed requests.

9

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Protocol

#on_connect, #on_read, #send_message

Constructor Details

#initialize(opts) ⇒ Handler

Prepares an RPC connection and sets #status to ‘:idle`.

Parameters:

  • opts (Hash)

Options Hash (opts):

  • :max_retries (Integer) — default: 9

    Default amount of tries for failed requests.

  • :base (Client)

    Client instance needed to push ourselves back to its connection pool once we’re done and we’re ready to be reused.



43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/arachni/rpc/client/handler.rb', line 43

def initialize( opts )
    @opts = opts.dup

    @max_retries = @opts[:max_retries] || DEFAULT_TRIES
    @client      = @opts[:client]

    @opts[:tries] ||= 0
    @tries ||= @opts[:tries]

    @status  = :idle
    @request = nil
end

Instance Attribute Details

#errorExceptions::ConnectionError (readonly)



32
33
34
# File 'lib/arachni/rpc/client/handler.rb', line 32

def error
  @error
end

#statusSymbol (readonly)

  • ‘:idle` – Just initialized.

  • ‘:ready` – A connection has been established.

  • ‘:pending` – Sending request and awaiting response.

  • ‘:done` – Response received and callback invoked – ready to be reused.

  • ‘:closed` – Connection closed.

Returns:

  • (Symbol)

    Status of the connection, can be:



29
30
31
# File 'lib/arachni/rpc/client/handler.rb', line 29

def status
  @status
end

Instance Method Details

#close_without_retryObject

Closes the connection without triggering a retry operation and sets #status to ‘:closed`.



124
125
126
127
128
# File 'lib/arachni/rpc/client/handler.rb', line 124

def close_without_retry
    @request = nil
    @status  = :closed
    close_without_callback
end

#done?Boolean

Note:

If ‘true`, the connection can be re-used.

Returns ‘true` when the connection is done, `false` otherwise.

Returns:

  • (Boolean)

    ‘true` when the connection is done, `false` otherwise.



118
119
120
# File 'lib/arachni/rpc/client/handler.rb', line 118

def done?
    @status == :done
end

#on_close(reason) ⇒ Object

Handles closed connections, cleans up the SSL session, retries (if necessary) and sets #status to ‘:closed`.



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/arachni/rpc/client/handler.rb', line 91

def on_close( reason )
     if @request
         # If there is a request and a callback and the callback hasn't yet be
         # called (i.e. not done) then we got here by error so retry.
         if @request && @request.callback && !done?
             if retry?
                 retry_request
             else
                 @error = e = Exceptions::ConnectionError.new( "Connection closed [#{reason}]" )
                 @request.callback.call( e )
                 @client.connection_failed self
             end

             return
         end
     else
         @error = reason
         @client.connection_failed self
     end

    close_without_retry
end

#receive_response(res) ⇒ Object

Note:

Pushes itself to the client’s connection pool to be re-used.

Handles responses to RPC requests, calls its callback and sets #status to ‘:done`.

Parameters:



72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/arachni/rpc/client/handler.rb', line 72

def receive_response( res )
    if res.exception?
        res.obj = Exceptions.from_response( res )
    end

    @request.callback.call( res.obj ) if @request.callback
ensure
    @request = nil # Help the GC out.
    @error   = nil # Help the GC out.
    @status  = :done

    @opts[:tries] = @tries = 0
    @client.push_connection self
end

#send_request(req) ⇒ Object

Sends an RPC request (i.e. performs an RPC call) and sets #status to ‘:pending`.

Parameters:



60
61
62
63
64
# File 'lib/arachni/rpc/client/handler.rb', line 60

def send_request( req )
    @request = req
    @status  = :pending
    super( req )
end