jr 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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