bertclient 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/bertclient.rb +114 -0
  2. metadata +55 -0
data/lib/bertclient.rb ADDED
@@ -0,0 +1,114 @@
1
+ require 'openssl'
2
+ require 'bert'
3
+ require 'resolv-replace' # TCPSocket
4
+
5
+ module BERT
6
+ class Client
7
+ class RPCError < StandardError; end
8
+ class NoSuchModule < RPCError; end
9
+ class NoSuchFunction < RPCError; end
10
+ class UserError < RPCError; end
11
+ class UnknownError < RPCError; end
12
+ class InvalidResponse < RPCError; end
13
+ class BadHeader < RPCError; end
14
+ class BadData < RPCError; end
15
+
16
+ def initialize(opts={})
17
+ @host = opts[:host] || 'localhost'
18
+ @port = opts[:port] || 9999
19
+ @ssl = opts[:ssl] || false
20
+ @verify_ssl = opts.has_key?(:verify_ssl) ? opts[:verify_ssl] : true
21
+ @socket = {}
22
+ connect
23
+ end
24
+
25
+ def call(mod, fun, *args)
26
+ response = cast_or_call(:call, mod, fun, *args)
27
+ return response[1] if response[0] == :reply
28
+
29
+ handle_error(response)
30
+ end
31
+
32
+ def cast(mod, fun, *args)
33
+ response = cast_or_call(:cast, mod, fun, *args)
34
+ return nil if response[0] == :noreply
35
+
36
+ handle_error(response)
37
+ end
38
+
39
+ # Wrapper for both cast and call mechanisms
40
+ def cast_or_call(cc, mod, fun, *args)
41
+ req = t[cc, mod.to_sym, fun.to_sym, args]
42
+ write_berp(req)
43
+ read_berp
44
+ end
45
+
46
+ # See bert-rpc.org for error response mechanisms
47
+ def handle_error(response)
48
+ unless response[0] == :error
49
+ raise InvalidReponse, "Expected error response, got: #{response.inspect}"
50
+ end
51
+
52
+ type, code, klass, detail, backtrace = response[1]
53
+ case type
54
+ when :server
55
+ if code == 1
56
+ raise NoSuchModule
57
+ elsif code == 2
58
+ raise NoSuchFunction
59
+ else
60
+ raise UnknownError, "Unknown server error: #{response.inspect}"
61
+ end
62
+ when :user
63
+ raise UserError.new("#{klass}: #{detail}\n#{backtrace.join()}")
64
+ when :protocol
65
+ if code == 1
66
+ raise BadHeader
67
+ elsif code == 2
68
+ raise BadData
69
+ else
70
+ raise UnknownError, "Unknown protocol error: #{reponse.inspect}"
71
+ end
72
+ else
73
+ raise UnknownError, "Unknown error: #{response.inspect}"
74
+ end
75
+ end
76
+
77
+ def socket
78
+ @socket[Thread.current]
79
+ end
80
+
81
+ # Open socket to service, use SSL if necessary
82
+ def connect
83
+ sock = TCPSocket.new(@host, @port)
84
+ if @ssl
85
+ sock = OpenSSL::SSL::SSLSocket.new(sock)
86
+ sock.sync_close = true
87
+ sock.connect
88
+ sock.post_connection_check(@host) if @verify_ssl
89
+ end
90
+ @socket[Thread.current] = sock
91
+ true
92
+ end
93
+
94
+ # Reads a new berp from the socket and returns the decoded object
95
+ def read_berp
96
+ length = socket.read(4).unpack('N')[0]
97
+ data = socket.read(length)
98
+ BERT.decode(data)
99
+ end
100
+
101
+ # Accepts a Ruby object, converts to a berp and sends through the socket
102
+ def write_berp(obj)
103
+ socket.write(Client.create_berp(obj))
104
+ end
105
+
106
+ # Accepts a Ruby object and returns an encoded berp
107
+ def Client.create_berp(obj)
108
+ data = BERT.encode(obj)
109
+ length = [data.bytesize].pack('N')
110
+ "#{length}#{data}"
111
+ end
112
+ end
113
+
114
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bertclient
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - Jared Kuolt
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-03-23 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: BERT::Client is a threadsafe BERT-RPC client with support for persistent connections, ssl, and it currently exposes BERT-RPC's cast and call
17
+ email: luckythetourist@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/bertclient.rb
26
+ has_rdoc: true
27
+ homepage: http://github.com/luckythetourist/bertclient
28
+ licenses: []
29
+
30
+ post_install_message:
31
+ rdoc_options: []
32
+
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: "0"
40
+ version:
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ version:
47
+ requirements: []
48
+
49
+ rubyforge_project: bertclient
50
+ rubygems_version: 1.3.5
51
+ signing_key:
52
+ specification_version: 3
53
+ summary: A threadsafe BERT-RPC client with ssl support and persistent connections
54
+ test_files: []
55
+