jsonrpc2 0.0.7 → 0.0.8

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.
@@ -2,6 +2,22 @@
2
2
 
3
3
  A Rack compatible, documenting JSON-RPC 2 DSL/server implementation for ruby.
4
4
 
5
+ ## Changes
6
+
7
+ * 0.0.8 - 3-Sep-2012
8
+ Add #request to access Rack::Request object
9
+ Make URLs in HTML interface clickable
10
+
11
+ * 0.0.7 - 27-Aug-2012
12
+ Add bundled Bootstrap assets for HTML test interface
13
+
14
+ * 0.0.6 - 24-Aug-2012
15
+ Add Date/Time/DateTime as special string types with regex checks for validation
16
+
17
+ * 0.0.5 - 19-Jul-2012
18
+ Add commandline client jsonrpc2
19
+ Add #auth to access currently authenticated username
20
+
5
21
  ## Features
6
22
 
7
23
  * Inline documentation
@@ -167,9 +167,12 @@ EOS
167
167
  end
168
168
  # Format JSON result
169
169
  def format_result(result)
170
- CGI.escapeHTML(JSON.pretty_unparse(JSON.parse(result)))
171
- rescue Exception
172
- result
170
+ CGI.escapeHTML(JSON.pretty_unparse(JSON.parse(result))).gsub(%r<("|&quot;)https?://[^"]+?("|&quot;)>) do |str|
171
+ url = CGI.unescapeHTML(str)[1...-1]
172
+ %Q["<a href="#{CGI.escapeHTML(url)}">#{CGI.escapeHTML(url)}</a>"]
173
+ end
174
+ rescue Exception => e
175
+ CGI.escapeHTML(result.to_s)
173
176
  end
174
177
  end
175
178
  end
@@ -17,7 +17,7 @@ module JSONRPC2
17
17
 
18
18
  # Base class for JSONRPC2 interface
19
19
  class Interface
20
- class << self
20
+ class << self
21
21
 
22
22
  # @!group Authentication
23
23
 
@@ -25,13 +25,13 @@ class Interface
25
25
  #
26
26
  # @param [#check] args An object that responds to check(environment, json_call_data)
27
27
  # @return [#check, nil] Currently set object or nil
28
- def auth_with *args
29
- if args.empty?
30
- return @auth_with
31
- else
32
- @auth_with = args[0]
33
- end
34
- end
28
+ def auth_with *args
29
+ if args.empty?
30
+ return @auth_with
31
+ else
32
+ @auth_with = args[0]
33
+ end
34
+ end
35
35
 
36
36
  # @!endgroup
37
37
 
@@ -66,14 +66,15 @@ class Interface
66
66
 
67
67
  # @!endgroup
68
68
 
69
- end
69
+ end
70
70
 
71
71
  # Create new interface object
72
72
  #
73
73
  # @param [Hash] env Rack environment
74
- def initialize(env)
75
- @env = env
76
- end
74
+ def initialize(env)
75
+ @_jsonrpc_env = env
76
+ @_jsonrpc_request = Rack::Request.new(env)
77
+ end
77
78
  # Internal
78
79
  def rack_dispatch(rpcData)
79
80
  catch(:rack_response) do
@@ -87,54 +88,58 @@ class Interface
87
88
  # @param [Hash,Array] rpc_data Array of calls or Hash containing one call
88
89
  # @return [Hash,Array] Depends on input, but either a hash result or an array of results corresponding to calls.
89
90
  def dispatch(rpc_data)
90
- case rpc_data
91
+ case rpc_data
91
92
  when Array
92
- rpc_data.map { |rpc| dispatch_single(rpc) }.to_json
93
- else
94
- dispatch_single(rpc_data).to_json
95
- end
96
- end
93
+ rpc_data.map { |rpc| dispatch_single(rpc) }.to_json
94
+ else
95
+ dispatch_single(rpc_data).to_json
96
+ end
97
+ end
97
98
 
98
- protected
99
+ protected
99
100
  # JSON result helper
100
- def response_ok(id, result)
101
- { 'jsonrpc' => '2.0', 'result' => result, 'id' => id }
102
- end
101
+ def response_ok(id, result)
102
+ { 'jsonrpc' => '2.0', 'result' => result, 'id' => id }
103
+ end
103
104
  # JSON error helper
104
- def response_error(code, message, data)
105
- { 'jsonrpc' => '2.0', 'error' => { 'code' => code, 'message' => message, 'data' => data }, 'id' => (@jsonrpc_call && @jsonrpc_call['id'] || nil) }
106
- end
105
+ def response_error(code, message, data)
106
+ { 'jsonrpc' => '2.0', 'error' => { 'code' => code, 'message' => message, 'data' => data }, 'id' => (@_jsonrpc_call && @_jsonrpc_call['id'] || nil) }
107
+ end
107
108
  # Params helper
108
109
  def params
109
- @jsonrpc_call['params']
110
+ @_jsonrpc_call['params']
110
111
  end
111
112
  # Auth info
112
113
  def auth
113
- @jsonrpc_auth
114
+ @_jsonrpc_auth
115
+ end
116
+ # Rack::Request
117
+ def request
118
+ @_jsonrpc_request
114
119
  end
115
120
  # Check call validity and authentication & make a single method call
116
121
  #
117
122
  # @param [Hash] rpc JSON-RPC-2 call
118
- def dispatch_single(rpc)
119
- unless rpc.has_key?('id') && rpc.has_key?('method') && rpc['jsonrpc'].eql?('2.0')
120
- return response_error(-32600, 'Invalid request', nil)
121
- end
122
- @jsonrpc_call = rpc
123
-
124
- begin
125
- if self.class.auth_with && ! @jsonrpc_auth
126
- (@jsonrpc_auth = self.class.auth_with.client_check(@env, rpc)) or raise AuthFail, "Invalid credentials"
123
+ def dispatch_single(rpc)
124
+ unless rpc.has_key?('id') && rpc.has_key?('method') && rpc['jsonrpc'].eql?('2.0')
125
+ return response_error(-32600, 'Invalid request', nil)
126
+ end
127
+ @_jsonrpc_call = rpc
128
+
129
+ begin
130
+ if self.class.auth_with && ! @_jsonrpc_auth
131
+ (@_jsonrpc_auth = self.class.auth_with.client_check(@_jsonrpc_env, rpc)) or raise AuthFail, "Invalid credentials"
127
132
  end
128
133
 
129
- call(rpc['method'], rpc['id'], rpc['params'])
130
- rescue AuthFail => e
131
- response_error(-32000, "AuthFail: #{e.class}: #{e.message}", {}) # XXX: Change me
132
- rescue APIFail => e
133
- response_error(-32000, "APIFail: #{e.class}: #{e.message}", {}) # XXX: Change me
134
- rescue Exception => e
135
- response_error(-32000, "#{e.class}: #{e.message}", e.backtrace) # XXX: Change me
136
- end
137
- end
134
+ call(rpc['method'], rpc['id'], rpc['params'])
135
+ rescue AuthFail => e
136
+ response_error(-32000, "AuthFail: #{e.class}: #{e.message}", {}) # XXX: Change me
137
+ rescue APIFail => e
138
+ response_error(-32000, "APIFail: #{e.class}: #{e.message}", {}) # XXX: Change me
139
+ rescue Exception => e
140
+ response_error(-32000, "#{e.class}: #{e.message}", e.backtrace) # XXX: Change me
141
+ end
142
+ end
138
143
  # List API methods
139
144
  #
140
145
  # @return [Array] List of api method names
@@ -148,41 +153,41 @@ class Interface
148
153
  # @param [Integer] id Method call ID - for response
149
154
  # @param [Hash] params Method parameters
150
155
  # @return [Hash] JSON response
151
- def call(method, id, params)
152
- if api_methods.include?(method)
153
- begin
154
- Types.valid_params?(self.class, method, params)
155
- rescue Exception => e
156
- return response_error(-32602, "Invalid params - #{e.message}", {})
157
- end
156
+ def call(method, id, params)
157
+ if api_methods.include?(method)
158
+ begin
159
+ Types.valid_params?(self.class, method, params)
160
+ rescue Exception => e
161
+ return response_error(-32602, "Invalid params - #{e.message}", {})
162
+ end
158
163
 
159
164
  if self.method(method).arity.zero?
160
- result = send(method)
165
+ result = send(method)
161
166
  else
162
- result = send(method, params)
167
+ result = send(method, params)
163
168
  end
164
169
 
165
- begin
166
- Types.valid_result?(self.class, method, result)
167
- rescue Exception => e
168
- return response_error(-32602, "Invalid result - #{e.message}", {})
169
- end
170
-
171
- response_ok(id, result)
172
- else
173
- response_error(-32601, "Unknown method `#{method.inspect}'", {})
174
- end
175
- end
176
-
177
- class << self
170
+ begin
171
+ Types.valid_result?(self.class, method, result)
172
+ rescue Exception => e
173
+ return response_error(-32602, "Invalid result - #{e.message}", {})
174
+ end
175
+
176
+ response_ok(id, result)
177
+ else
178
+ response_error(-32601, "Unknown method `#{method.inspect}'", {})
179
+ end
180
+ end
181
+
182
+ class << self
178
183
  # Store parameter in internal hash when building API
179
- def ___append_param name, type, options
180
- @params ||= []
181
- unless options.has_key?(:required)
182
- options[:required] = true
183
- end
184
- @params << options.merge({ :name => name, :type => type })
185
- end
184
+ def ___append_param name, type, options
185
+ @params ||= []
186
+ unless options.has_key?(:required)
187
+ options[:required] = true
188
+ end
189
+ @params << options.merge({ :name => name, :type => type })
190
+ end
186
191
  private :___append_param
187
192
 
188
193
  # @!group DSL
@@ -191,119 +196,119 @@ class Interface
191
196
  #
192
197
  # @param [String] name parameter name
193
198
  # @param [String] type description of type see {Types}
194
- def param name, type, desc = nil, options = nil
195
- if options.nil? && desc.is_a?(Hash)
196
- options, desc = desc, nil
197
- end
198
- options ||= {}
199
- options[:desc] = desc if desc.is_a?(String)
200
-
201
- ___append_param name, type, options
202
- end
199
+ def param name, type, desc = nil, options = nil
200
+ if options.nil? && desc.is_a?(Hash)
201
+ options, desc = desc, nil
202
+ end
203
+ options ||= {}
204
+ options[:desc] = desc if desc.is_a?(String)
205
+
206
+ ___append_param name, type, options
207
+ end
203
208
 
204
209
  # Define an optional parameter for next method
205
- def optional name, type, desc = nil, options = nil
206
- if options.nil? && desc.is_a?(Hash)
207
- options, desc = desc, nil
208
- end
209
- options ||= {}
210
- options[:desc] = desc if desc.is_a?(String)
210
+ def optional name, type, desc = nil, options = nil
211
+ if options.nil? && desc.is_a?(Hash)
212
+ options, desc = desc, nil
213
+ end
214
+ options ||= {}
215
+ options[:desc] = desc if desc.is_a?(String)
211
216
 
212
- ___append_param(name, type, options.merge(:required => false))
213
- end
217
+ ___append_param(name, type, options.merge(:required => false))
218
+ end
214
219
 
215
220
  # Define type of return value for next method
216
- def result type, desc = nil
217
- @result = { :type => type, :desc => desc }
218
- end
221
+ def result type, desc = nil
222
+ @result = { :type => type, :desc => desc }
223
+ end
219
224
 
220
225
  # Set description for next method
221
- def desc str
222
- @desc = str
223
- end
226
+ def desc str
227
+ @desc = str
228
+ end
224
229
 
225
230
  # Add an example for next method
226
- def example desc, code
227
- @examples ||= []
228
- @examples << { :desc => desc, :code => code }
229
- end
231
+ def example desc, code
232
+ @examples ||= []
233
+ @examples << { :desc => desc, :code => code }
234
+ end
230
235
 
231
236
  # Define a custom type
232
- def type name, *fields
233
- @types ||= {}
234
- type = JsonObjectType.new(name, fields)
237
+ def type name, *fields
238
+ @types ||= {}
239
+ type = JsonObjectType.new(name, fields)
235
240
 
236
- if block_given?
237
- yield(type)
238
- end
241
+ if block_given?
242
+ yield(type)
243
+ end
239
244
 
240
- @types[name] = type
241
- end
245
+ @types[name] = type
246
+ end
242
247
 
243
248
  # Group methods
244
- def section name, summary=nil
245
- @sections ||= []
246
- @sections << {:name => name, :summary => summary}
247
-
248
- @current_section = name
249
- if block_given?
250
- yield
251
- @current_section = nil
252
- end
253
- end
249
+ def section name, summary=nil
250
+ @sections ||= []
251
+ @sections << {:name => name, :summary => summary}
252
+
253
+ @current_section = name
254
+ if block_given?
255
+ yield
256
+ @current_section = nil
257
+ end
258
+ end
254
259
 
255
260
  # Exclude next method from documentation
256
- def nodoc
257
- @nodoc = true
258
- end
261
+ def nodoc
262
+ @nodoc = true
263
+ end
259
264
 
260
265
  # Set interface title
261
- def title str = nil
262
- @title = str if str
263
- end
266
+ def title str = nil
267
+ @title = str if str
268
+ end
264
269
 
265
270
  # Sets introduction for interface
266
- def introduction str = nil
267
- @introduction = str if str
268
- end
271
+ def introduction str = nil
272
+ @introduction = str if str
273
+ end
269
274
 
270
275
  # @!endgroup
271
276
 
272
277
  # Catch methods added to class & store documentation
273
- def method_added(name)
274
- return if self == JSONRPC2::Interface
275
- @about ||= {}
276
- method = {}
277
- method[:params] = @params if @params
278
- method[:returns] = @result if @result
279
- method[:desc] = @desc if @desc
280
- method[:examples] = @examples if @examples
281
-
282
- if method.empty?
283
- if public_methods(false).include?(name)
284
- unless @nodoc
285
- #logger.info("#{name} has no API documentation... :(")
286
- end
287
- else
288
- #logger.debug("#{name} isn't public - so no API")
289
- end
290
- else
291
- method[:name] = name
292
- method[:section] = @current_section
293
- method[:index] = @about.size
294
- @about[name.to_s] = method
295
- end
296
-
297
- @result = nil
298
- @params = nil
299
- @desc = nil
300
- @examples = nil
301
- @nodoc = false
302
- end
278
+ def method_added(name)
279
+ return if self == JSONRPC2::Interface
280
+ @about ||= {}
281
+ method = {}
282
+ method[:params] = @params if @params
283
+ method[:returns] = @result if @result
284
+ method[:desc] = @desc if @desc
285
+ method[:examples] = @examples if @examples
286
+
287
+ if method.empty?
288
+ if public_methods(false).include?(name)
289
+ unless @nodoc
290
+ #logger.info("#{name} has no API documentation... :(")
291
+ end
292
+ else
293
+ #logger.debug("#{name} isn't public - so no API")
294
+ end
295
+ else
296
+ method[:name] = name
297
+ method[:section] = @current_section
298
+ method[:index] = @about.size
299
+ @about[name.to_s] = method
300
+ end
301
+
302
+ @result = nil
303
+ @params = nil
304
+ @desc = nil
305
+ @examples = nil
306
+ @nodoc = false
307
+ end
303
308
  private :method_added
304
- attr_reader :about, :types
309
+ attr_reader :about, :types
305
310
 
306
- end
311
+ end
307
312
 
308
313
  extend JSONRPC2::TextileEmitter
309
314
  end
@@ -1,5 +1,5 @@
1
1
  # JSONRPC2 namespace module
2
2
  module JSONRPC2
3
3
  # Version
4
- VERSION = "0.0.7"
4
+ VERSION = "0.0.8"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonrpc2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-27 00:00:00.000000000 Z
12
+ date: 2012-09-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: httpclient