Class: Ava::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/client/client.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host: 'localhost', port: 2016, key: nil) ⇒ Client

Returns a new instance of Client.



8
9
10
11
12
13
# File 'lib/client/client.rb', line 8

def initialize host: 'localhost', port: 2016, key: nil
  self.host = host
  self.port = port
  @client_id = {key: nil, iv: nil, encrypt: false}
  get_id(key) if key
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(*args, **named) ⇒ Object



61
62
63
64
65
66
67
# File 'lib/client/client.rb', line 61

def method_missing *args, **named
  if args.size == 1 && (named == {} || named.nil?) && registered_objects.any?{ |o| o.to_sym == args.first}
    Replicant.new args.first, self
  else
    request args.first, args[1], *args[2..-1], **named
  end
end

Instance Attribute Details

#hostObject

Returns the value of attribute host.



6
7
8
# File 'lib/client/client.rb', line 6

def host
  @host
end

#portObject

Returns the value of attribute port.



6
7
8
# File 'lib/client/client.rb', line 6

def port
  @port
end

#responseObject

Returns the value of attribute response.



6
7
8
# File 'lib/client/client.rb', line 6

def response
  @response
end

#socketObject

Returns the value of attribute socket.



6
7
8
# File 'lib/client/client.rb', line 6

def socket
  @socket
end

Instance Method Details

#closeObject



23
24
25
# File 'lib/client/client.rb', line 23

def close
  @socket.close if defined?(@socket)
end

#connectObject



19
20
21
# File 'lib/client/client.rb', line 19

def connect
  @socket = TCPSocket.open(@host, @port)
end

#decrypt_msg(msg) ⇒ Object



94
95
96
97
98
99
100
101
102
103
# File 'lib/client/client.rb', line 94

def decrypt_msg msg
  return msg if !@client_id[:encrypt] || !msg.include?(:encrypted)
  cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
  cipher.decrypt
  cipher.key = @client_id[:key]
  cipher.iv = @client_id[:iv]
  dec = cipher.update msg[:encrypted]
  dec << cipher.final
  YAML.load(YAML.load(dec))
end

#encrypt_msg(msg) ⇒ Object



83
84
85
86
87
88
89
90
91
92
# File 'lib/client/client.rb', line 83

def encrypt_msg msg
  return msg if !@client_id[:encrypt]
  cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
  cipher.encrypt
  cipher.key = @client_id[:key]
  cipher.iv = @client_id[:iv]
  enc = cipher.update msg.to_yaml
  enc << cipher.final
  {encrypted: enc, client_id: @client_id[:key]}.to_yaml
end

#get_id(key) ⇒ Object



27
28
29
30
31
32
33
34
35
36
# File 'lib/client/client.rb', line 27

def get_id key
  @client_id[:encrypt] = false
  response = request :controller, :secret_key, key
  if response
    @client_id = response
    true
  else
    false
  end
end

#inspectObject



15
16
17
# File 'lib/client/client.rb', line 15

def inspect
  "#<#{self.class}:#{self.object_id}>"
end

#missing_gemsObject



46
47
48
# File 'lib/client/client.rb', line 46

def missing_gems
  required_gems - Gem.loaded_specs.keys
end

#registered_objectsObject



38
39
40
# File 'lib/client/client.rb', line 38

def registered_objects
  request(:controller, :registered_objects)
end

#request(object, method, *args, **named) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/client/client.rb', line 69

def request object, method, *args, **named
  connect
  argument = (named.nil? ? {} : named).merge({args:args})
  request = {object => { method => argument }, client_id: @client_id[:key] }
  @socket.puts encrypt_msg(request.to_yaml)
  lines = Array.new
  while line = @socket.gets
    lines << line
  end
  @response = decrypt_msg(YAML.load(lines.join)).map{ |k,v| [k.to_sym, v]}.to_h
  close
  @response[:response] ? @response[:response] : (raise @response[:error])
end

#require_missing_gemsObject



50
51
52
53
54
55
56
57
58
59
# File 'lib/client/client.rb', line 50

def require_missing_gems
  missing_gems.map do |gem|
    begin
      require gem
      [gem, true]
    rescue
      [gem, false]
    end
  end.to_h
end

#required_gemsObject



42
43
44
# File 'lib/client/client.rb', line 42

def required_gems
  request(:controller, :required_gems)
end