Class: Rex::Proto::Thrift::Client
- Inherits:
-
Object
- Object
- Rex::Proto::Thrift::Client
- Includes:
- Rex::Proto::Thrift
- Defined in:
- lib/rex/proto/thrift/client.rb
Instance Attribute Summary collapse
-
#comm ⇒ Rex::Socket::Comm
readonly
An optional, explicit object to use for creating the connection.
-
#host ⇒ String
readonly
The Thrift server host.
-
#port ⇒ Integer
readonly
The Thrift server port.
-
#ssl ⇒ Boolean
readonly
Whether or not SSL is used for the connection.
-
#timeout ⇒ Integer
The communication timeout in seconds.
Instance Method Summary collapse
-
#call(method_name, *data, timeout: @timeout) ⇒ Array<Hash>
Call the specific method on the remote peer.
-
#close ⇒ NilClass
Close the connection to the remote server.
-
#connect(t = -1)) ⇒ NilClass
Establish the connection to the remote server.
-
#initialize(host, port, context: {}, ssl: false, ssl_version: nil, comm: nil, timeout: 10) ⇒ Client
constructor
A new instance of Client.
-
#recv_raw(timeout: @timeout) ⇒ String
Receive raw data from the remote peer.
-
#send_raw(data) ⇒ Object
Send raw data to the remote peer.
Constructor Details
#initialize(host, port, context: {}, ssl: false, ssl_version: nil, comm: nil, timeout: 10) ⇒ Client
Returns a new instance of Client.
22 23 24 25 26 27 28 29 30 |
# File 'lib/rex/proto/thrift/client.rb', line 22 def initialize(host, port, context: {}, ssl: false, ssl_version: nil, comm: nil, timeout: 10) @host = host @port = port @context = context @ssl = ssl @ssl_version = ssl_version @comm = comm @timeout = timeout end |
Instance Attribute Details
#comm ⇒ Rex::Socket::Comm (readonly)
Returns An optional, explicit object to use for creating the connection.
16 17 18 |
# File 'lib/rex/proto/thrift/client.rb', line 16 def comm @comm end |
#host ⇒ String (readonly)
Returns The Thrift server host.
7 8 9 |
# File 'lib/rex/proto/thrift/client.rb', line 7 def host @host end |
#port ⇒ Integer (readonly)
Returns The Thrift server port.
10 11 12 |
# File 'lib/rex/proto/thrift/client.rb', line 10 def port @port end |
#ssl ⇒ Boolean (readonly)
Returns Whether or not SSL is used for the connection.
13 14 15 |
# File 'lib/rex/proto/thrift/client.rb', line 13 def ssl @ssl end |
#timeout ⇒ Integer
Returns The communication timeout in seconds.
20 21 22 |
# File 'lib/rex/proto/thrift/client.rb', line 20 def timeout @timeout end |
Instance Method Details
#call(method_name, *data, timeout: @timeout) ⇒ Array<Hash>
Call the specific method on the remote peer.
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/rex/proto/thrift/client.rb', line 115 def call(method_name, *data, timeout: @timeout) tx_header = ThriftHeader.new(method_name: method_name, message_type: ThriftMessageType::CALL) tx_data = data.map do |part| case part when BinData::Struct part.to_binary_s when Hash ThriftData.new(part).to_binary_s else part end end send_raw(tx_header.to_binary_s + tx_data.join) rx_data = recv_raw(timeout: timeout) rx_header = ThriftHeader.read(rx_data) unless rx_header. == ThriftMessageType::REPLY raise Error::UnexpectedReplyError.new(rx_header, 'The received header was not a REPLY message.') end unless rx_header.method_name == method_name raise Error::UnexpectedReplyError.new(rx_header, 'The received header was not to the expected method.') end ThriftStruct.read(rx_data[rx_header.num_bytes..]).snapshot end |
#close ⇒ NilClass
Close the connection to the remote server.
55 56 57 58 59 60 61 62 |
# File 'lib/rex/proto/thrift/client.rb', line 55 def close if @conn && !@conn.closed? @conn.shutdown @conn.close end @conn = nil end |
#connect(t = -1)) ⇒ NilClass
Establish the connection to the remote server.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/rex/proto/thrift/client.rb', line 36 def connect(t = -1) timeout = (t.nil? or t == -1) ? @timeout : t @conn = Rex::Socket::Tcp.create( 'PeerHost' => @host, 'PeerPort' => @port.to_i, 'Context' => @context, 'SSL' => @ssl, 'SSLVersion' => @ssl_version, 'Timeout' => timeout, 'Comm' => @comm ) nil end |
#recv_raw(timeout: @timeout) ⇒ String
Receive raw data from the remote peer.
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 104 105 |
# File 'lib/rex/proto/thrift/client.rb', line 76 def recv_raw(timeout: @timeout) remaining = timeout frame_size, elapsed_time = Rex::Stopwatch.elapsed_time do @conn.get_once(4, remaining) end remaining -= elapsed_time if frame_size.nil? || frame_size.length < 4 raise Rex::TimeoutError, 'Failed to read the response data length due to timeout.' end frame_size = frame_size.unpack1('N') body = '' while (body.size < frame_size) && remaining > 0 chunk, elapsed_time = Rex::Stopwatch.elapsed_time do @conn.read(frame_size - body.size, remaining) end remaining -= elapsed_time body << chunk end unless body.size == (frame_size) if remaining <= 0 raise Rex::TimeoutError, 'Failed to read the response data due to timeout.' end raise Error::InvalidFrameError.new end body end |
#send_raw(data) ⇒ Object
Send raw data to the remote peer.
67 68 69 |
# File 'lib/rex/proto/thrift/client.rb', line 67 def send_raw(data) @conn.put([data.length].pack('N') + data) end |