jr 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data.tar.gz.sig +0 -0
  2. data/README +14 -0
  3. data/lib/jr.rb +147 -0
  4. metadata +88 -0
  5. metadata.gz.sig +2 -0
Binary file
data/README ADDED
@@ -0,0 +1,14 @@
1
+ Jr.
2
+ ---
3
+
4
+ Jr. is a Ruby library for communicating with JSON RPC servers. Unfortunately,
5
+ Jr. currently only supports HTTP JSON RPC servers.
6
+
7
+ Example Usage
8
+ -------------
9
+
10
+ # Connect to the JSON RPC at https://user:password@127.0.0.1:1234/
11
+ jr = Jr::Jr.new('127.0.0.1', 1234, 'user', 'password', use_ssl=true)
12
+
13
+ jr.request(:function, 'arg1', 'arg2') # 'response'
14
+ jr.function('arg1', 'arg2') # 'response'
@@ -0,0 +1,147 @@
1
+ require 'json'
2
+ require 'socket'
3
+ require 'base64'
4
+ require 'openssl'
5
+ require 'net/http'
6
+
7
+ JSON_RPC_VERSION = '2.0'
8
+
9
+ module Jr
10
+ class Error < Exception
11
+ @@message = 'There was an error communicating with the JSON RPC server.'
12
+
13
+ # @jr is the instance of JR that raised the exception.
14
+ attr_reader :jr
15
+
16
+ def initialize(jr, msg=@@message)
17
+ @jr = jr
18
+
19
+ super(msg)
20
+ end
21
+ end
22
+
23
+ class AuthenticationError < Error
24
+ @@message = 'There was an error authenticating to the JSON RPC server.'
25
+ end
26
+
27
+ class IDMismatch < Error
28
+ @@message = 'The server sent us a response with an unexpected id.'
29
+ end
30
+
31
+ # ProtocolMismatch is raised when value of 'rpcjson' returned by the server
32
+ # does not match JSON_RPC_VERSION. Because of errors in JSON RPC servers, it
33
+ # is *NOT* raised if 'rpcjson' is omitted, even though that is required by the
34
+ # (draft) specification.
35
+ class ProtocolMismatch < Error
36
+ def initialize(jr, version)
37
+ super(jr, "We expected to receive a version '#{JSON_RPC_VERSION}' "\
38
+ "response, but actually got a #{version.inspect} one.")
39
+ end
40
+ end
41
+
42
+ # ReservedMethod is raised if a method beginning with 'rpc' is called.
43
+ class ReservedMethod < Error
44
+ @@message = '%s is a reserved method'
45
+
46
+ # @method is the name of the reserved method.
47
+ attr_reader :method
48
+
49
+ def initialize(jr, method, msg=@@message)
50
+ @method = method
51
+ super(jr, meth % msg)
52
+ end
53
+ end
54
+
55
+ # ServerError is raised when the server requests (via the error property) that
56
+ # an exception be raised in client code.
57
+ class ServerError < Exception
58
+ # @code is a Fixnum specifying the type of the error.
59
+ attr_reader :code
60
+ # @message is a String providing a short description of the error.
61
+ attr_reader :message
62
+ # @data is an Object providing additional information about the error.
63
+ attr_reader :data
64
+
65
+ def initialize(jr, code, message, data)
66
+ @code, @message, @data = code, message, data
67
+
68
+ super(jr, "Error %d: %s" % [code, message])
69
+ end
70
+ end
71
+
72
+ # Jr lets you communicate with an HTTP JSON RPC server.
73
+ class Jr
74
+ attr_reader :host, :port, :user, :password, :ssl
75
+
76
+ # @connection is a Net::HTTP.
77
+ attr_reader :connection
78
+
79
+ def initialize(host, port, user=nil, password=nil, ssl=false)
80
+ %w{host user port password ssl}.each do |var|
81
+ instance_variable_set("@#{var}", eval(var))
82
+ end
83
+ end
84
+
85
+ # Call method on the server, and return the result.
86
+ def request(method, *args)
87
+ if method.start_with?('rpc')
88
+ raise ReservedMethod.new(method)
89
+ end
90
+
91
+ reqid = get_request_id()
92
+ data = JSON.dump(
93
+ jsonrpc: '2.0',
94
+ method: method.to_s,
95
+ params: args,
96
+ id: reqid
97
+ )
98
+
99
+ r = JSON.parse(http_request(data))
100
+ if r.has_key?('jsonrpc') and (r['jsonrpc'] != JSON_RPC_VERSION)
101
+ # Even though the JSON RPC specification requires that a 'jsonrpc' key
102
+ # is present, we don't require it because not all servers implement it.
103
+ raise ProtocolMismatch.new(self, r['jsonrpc'])
104
+ elsif r['id'] != reqid
105
+ raise ProtocolMismatch.new(IDMismatch, self)
106
+ elsif r['error']
107
+ raise ServerError.new(self, r['error']['code'], r['error']['message'],
108
+ r['error']['data'])
109
+ end
110
+
111
+ r['result']
112
+ end
113
+
114
+ def method_missing(meth, *args)
115
+ request(meth, *args)
116
+ end
117
+
118
+ private
119
+
120
+ # We return the unparsed response of the JSON RPC server to the serialized
121
+ # request data.
122
+ def http_request(data)
123
+ unless @connection
124
+ @connection = Net::HTTP.new(@host, @port)
125
+ @connection.use_ssl = @ssl
126
+ end
127
+
128
+ req = Net::HTTP::Post.new('/')
129
+ req.basic_auth(@user, @password)
130
+ req.content_type = 'multipart/form_data'
131
+ req.body = data
132
+
133
+ resp = @connection.request(req)
134
+ if Net::HTTPUnauthorized === resp
135
+ raise AuthenticationError.new(self)
136
+ end
137
+
138
+ resp.body()
139
+ end
140
+
141
+ # Generate a request ID. We use a random string for this.
142
+ def get_request_id()
143
+ @random_instance ||= Random.new
144
+ Base64.urlsafe_encode64(@random_instance.bytes(12))
145
+ end
146
+ end
147
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - katmagic
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain:
12
+ - ! '-----BEGIN CERTIFICATE-----
13
+
14
+ MIIDQDCCAiigAwIBAgIBADANBgkqhkiG9w0BAQUFADBGMRgwFgYDVQQDDA90aGUu
15
+
16
+ bWFnaWNhbC5rYXQxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixk
17
+
18
+ ARkWA2NvbTAeFw0xMTA4MjEyMjMyMDFaFw0xMjA4MjAyMjMyMDFaMEYxGDAWBgNV
19
+
20
+ BAMMD3RoZS5tYWdpY2FsLmthdDEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYK
21
+
22
+ CZImiZPyLGQBGRYDY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
23
+
24
+ pBt20nwjs5W03djpRN6FAbpiio286NHMTk6HhmjV6GZKOi5ZUX5onTnKUg2Vc35z
25
+
26
+ /nK+aIPReyRfBgIcfSjhoXh1A1Dp+2laNgTtU/3eMupruatgORAPCSaG9Ns+HSyR
27
+
28
+ vySbz1QUrwvlvF0qkhhApNQ6dsLl2LMOV3QcluY+Y3CVccOWOSHdQcnAbPuzM9Hf
29
+
30
+ 4ChI4OGL7+DwLA5OK2S5uewRAa2iLkJSN0WugnQlJqMT59GRaqTDOtnYQpiyKEBy
31
+
32
+ QjVPO4LNk7iDsJP22YBrveIzm8/YYRBTU4LTHMEMOyCszrYqD2S1Lwp2rtCJzQCl
33
+
34
+ BA0LtBKrZl5mwZm7qyj+TwIDAQABozkwNzAJBgNVHRMEAjAAMB0GA1UdDgQWBBSm
35
+
36
+ s5arhjp61kmGl6wsmLYkqerdqDALBgNVHQ8EBAMCBLAwDQYJKoZIhvcNAQEFBQAD
37
+
38
+ ggEBAA6cQNQMOPRy4yrj7Nh5Mb9qq8t/8ho/JQvjzVof9qRd+kfKrOoOhXfEO+Rm
39
+
40
+ sWcaOnBCVC4DnZuNDSLygVhCDtMnHjg/JsfO/GBF/QlNTJOO1jkoQiS6w0KARlBm
41
+
42
+ cpXaWg/oMtXJ2PaUga6WkNeXYf9Mad36P4yuGQScjs+WkUUy7DNZvTGReIcCWOR8
43
+
44
+ jteSvvCMobQKGr2DfFOU9Jiddh2FPpz/KOM2ijzwsVNUMUr7R58LoCnQZrZ/YaRW
45
+
46
+ ob6QnVgwqu5SUAKQxlFJ/aKlPMj735z8EogaZC1ZHgg3vkgGGyu57N/8BDDG0TzC
47
+
48
+ Zn3u2leVae/fJ03zYGArhuJKPgc=
49
+
50
+ -----END CERTIFICATE-----
51
+
52
+ '
53
+ date: 2012-02-17 00:00:00.000000000 Z
54
+ dependencies: []
55
+ description: Jr. lets you communicate with an HTTP JSON RPC server.
56
+ email: the.magical.kat@gmail.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - README
62
+ - lib/jr.rb
63
+ homepage: https://github.com/katmagic/jr
64
+ licenses: []
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 1.8.10
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: Jr. is a JSON RPC client implementation.
87
+ test_files: []
88
+ has_rdoc:
@@ -0,0 +1,2 @@
1
+ ս�{�QB�~����4�ħ0�ZT2ppw$�?��kbPd�"<#���c���(]t���߬��ę {�w�/ �`1#u�sň�R��ut�Ɣ~R^�1 ��o�С�[l�|��<1�N
2
+ R&8��G^H{A%̂��j|,��ٞ���]g