jimson 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,9 @@
1
+ == 0.3.1 / 2011-08-11
2
+
3
+ * Minor enhancements
4
+
5
+ * Refactor the way the server is intantiated/started to work better with config.ru
6
+
1
7
  == 0.3.0 / 2011-08-11
2
8
 
3
9
  * Major enhancements
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.3.1
@@ -1,13 +1,13 @@
1
1
  require 'rack'
2
2
  require 'rack/request'
3
3
  require 'rack/response'
4
- require 'rack/showexceptions'
5
4
  require 'json'
6
- require 'jimson/http_server'
7
5
 
8
6
  module Jimson
9
7
  class Server
10
8
 
9
+ JSON_RPC_VERSION = '2.0'
10
+
11
11
  attr_accessor :handler, :host, :port
12
12
 
13
13
  #
@@ -20,7 +20,6 @@ module Jimson
20
20
  #
21
21
  def initialize(handler, opts = {})
22
22
  @handler = handler
23
- @app = Jimson::HttpServer.new(@handler)
24
23
  @host = opts[:host] || '0.0.0.0'
25
24
  @port = opts[:port] || 8999
26
25
  @server = opts[:server] || 'webrick'
@@ -32,11 +31,139 @@ module Jimson
32
31
  def start
33
32
  Rack::Server.start(
34
33
  :server => @server,
35
- :app => @app,
34
+ :app => self,
36
35
  :Host => @host,
37
36
  :Port => @port
38
37
  )
39
38
  end
40
39
 
40
+ #
41
+ # Entry point for Rack
42
+ #
43
+ def call(env)
44
+ req = Rack::Request.new(env)
45
+ resp = Rack::Response.new
46
+ return resp.finish if !req.post?
47
+ resp.write process(req.body.read)
48
+ resp.finish
49
+ end
50
+
51
+ def process(content)
52
+ begin
53
+ request = parse_request(content)
54
+ if request.is_a?(Array)
55
+ raise Jimson::ServerError::InvalidRequest.new if request.empty?
56
+ response = request.map { |req| handle_request(req) }
57
+ else
58
+ response = handle_request(request)
59
+ end
60
+ rescue Jimson::ServerError::ParseError, Jimson::ServerError::InvalidRequest => e
61
+ response = error_response(e)
62
+ rescue Jimson::ServerError::Generic => e
63
+ response = error_response(e, request)
64
+ rescue StandardError, Exception
65
+ response = error_response(Jimson::ServerError::InternalError.new)
66
+ end
67
+
68
+ response.compact! if response.is_a?(Array)
69
+
70
+ return nil if response.nil? || (response.respond_to?(:empty?) && response.empty?)
71
+
72
+ response.to_json
73
+ end
74
+
75
+ def handle_request(request)
76
+ response = nil
77
+ begin
78
+ if !validate_request(request)
79
+ response = error_response(Jimson::ServerError::InvalidRequest.new)
80
+ else
81
+ response = create_response(request)
82
+ end
83
+ rescue Jimson::ServerError::Generic => e
84
+ response = error_response(e, request)
85
+ end
86
+
87
+ response
88
+ end
89
+
90
+ def validate_request(request)
91
+ required_keys = %w(jsonrpc method)
92
+ required_types = {
93
+ 'jsonrpc' => [String],
94
+ 'method' => [String],
95
+ 'params' => [Hash, Array],
96
+ 'id' => [String, Fixnum, NilClass]
97
+ }
98
+
99
+ return false if !request.is_a?(Hash)
100
+
101
+ required_keys.each do |key|
102
+ return false if !request.has_key?(key)
103
+ end
104
+
105
+ required_types.each do |key, types|
106
+ return false if request.has_key?(key) && !types.any? { |type| request[key].is_a?(type) }
107
+ end
108
+
109
+ return false if request['jsonrpc'] != JSON_RPC_VERSION
110
+
111
+ true
112
+ end
113
+
114
+ def create_response(request)
115
+ params = request['params']
116
+ begin
117
+ if params.is_a?(Hash)
118
+ result = @handler.send(request['method'], params)
119
+ else
120
+ result = @handler.send(request['method'], *params)
121
+ end
122
+ rescue NoMethodError
123
+ raise Jimson::ServerError::MethodNotFound.new
124
+ rescue ArgumentError
125
+ raise Jimson::ServerError::InvalidParams.new
126
+ rescue
127
+ raise Jimson::ServerError::ApplicationError.new($!)
128
+ end
129
+
130
+ response = success_response(request, result)
131
+
132
+ # A Notification is a Request object without an "id" member.
133
+ # The Server MUST NOT reply to a Notification, including those
134
+ # that are within a batch request.
135
+ response = nil if !request.has_key?('id')
136
+
137
+ response
138
+ end
139
+
140
+ def error_response(error, request = nil)
141
+ resp = {
142
+ 'jsonrpc' => JSON_RPC_VERSION,
143
+ 'error' => error.to_h,
144
+ }
145
+ if !!request && request.has_key?('id')
146
+ resp['id'] = request['id']
147
+ else
148
+ resp['id'] = nil
149
+ end
150
+
151
+ resp
152
+ end
153
+
154
+ def success_response(request, result)
155
+ {
156
+ 'jsonrpc' => JSON_RPC_VERSION,
157
+ 'result' => result,
158
+ 'id' => request['id']
159
+ }
160
+ end
161
+
162
+ def parse_request(post)
163
+ data = JSON.parse(post)
164
+ rescue
165
+ raise Jimson::ServerError::ParseError.new
166
+ end
167
+
41
168
  end
42
169
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jimson
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2011-08-11 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rest-client
16
- requirement: &17785440 !ruby/object:Gem::Requirement
16
+ requirement: &12229180 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.6.3
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *17785440
24
+ version_requirements: *12229180
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: json
27
- requirement: &17780040 !ruby/object:Gem::Requirement
27
+ requirement: &12228700 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 1.5.1
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *17780040
35
+ version_requirements: *12228700
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rack
38
- requirement: &17779580 !ruby/object:Gem::Requirement
38
+ requirement: &12225120 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: '1.3'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *17779580
46
+ version_requirements: *12225120
47
47
  description:
48
48
  email:
49
49
  executables: []
@@ -62,7 +62,6 @@ files:
62
62
  - lib/jimson/server_error.rb
63
63
  - lib/jimson/response.rb
64
64
  - lib/jimson/request.rb
65
- - lib/jimson/http_server.rb
66
65
  - lib/jimson/client.rb
67
66
  - spec/server_spec.rb
68
67
  - spec/client_spec.rb
@@ -1,138 +0,0 @@
1
- require 'jimson/server_error'
2
-
3
- module Jimson
4
- class HttpServer
5
-
6
- JSON_RPC_VERSION = '2.0'
7
-
8
- def initialize(handler)
9
- @handler = handler
10
- end
11
-
12
- def call(env)
13
- req = Rack::Request.new(env)
14
- resp = Rack::Response.new
15
- return resp.finish if !req.post?
16
- resp.write process(req.body.read)
17
- resp.finish
18
- end
19
-
20
- def process(content)
21
- begin
22
- request = parse_request(content)
23
- if request.is_a?(Array)
24
- raise Jimson::ServerError::InvalidRequest.new if request.empty?
25
- response = request.map { |req| handle_request(req) }
26
- else
27
- response = handle_request(request)
28
- end
29
- rescue Jimson::ServerError::ParseError, Jimson::ServerError::InvalidRequest => e
30
- response = error_response(e)
31
- rescue Jimson::ServerError::Generic => e
32
- response = error_response(e, request)
33
- rescue StandardError, Exception
34
- response = error_response(Jimson::ServerError::InternalError.new)
35
- end
36
-
37
- response.compact! if response.is_a?(Array)
38
-
39
- return nil if response.nil? || (response.respond_to?(:empty?) && response.empty?)
40
-
41
- response.to_json
42
- end
43
-
44
- def handle_request(request)
45
- response = nil
46
- begin
47
- if !validate_request(request)
48
- response = error_response(Jimson::ServerError::InvalidRequest.new)
49
- else
50
- response = create_response(request)
51
- end
52
- rescue Jimson::ServerError::Generic => e
53
- response = error_response(e, request)
54
- end
55
-
56
- response
57
- end
58
-
59
- def validate_request(request)
60
- required_keys = %w(jsonrpc method)
61
- required_types = {
62
- 'jsonrpc' => [String],
63
- 'method' => [String],
64
- 'params' => [Hash, Array],
65
- 'id' => [String, Fixnum, NilClass]
66
- }
67
-
68
- return false if !request.is_a?(Hash)
69
-
70
- required_keys.each do |key|
71
- return false if !request.has_key?(key)
72
- end
73
-
74
- required_types.each do |key, types|
75
- return false if request.has_key?(key) && !types.any? { |type| request[key].is_a?(type) }
76
- end
77
-
78
- return false if request['jsonrpc'] != JSON_RPC_VERSION
79
-
80
- true
81
- end
82
-
83
- def create_response(request)
84
- params = request['params']
85
- begin
86
- if params.is_a?(Hash)
87
- result = @handler.send(request['method'], params)
88
- else
89
- result = @handler.send(request['method'], *params)
90
- end
91
- rescue NoMethodError
92
- raise Jimson::ServerError::MethodNotFound.new
93
- rescue ArgumentError
94
- raise Jimson::ServerError::InvalidParams.new
95
- rescue
96
- raise Jimson::ServerError::ApplicationError.new($!)
97
- end
98
-
99
- response = success_response(request, result)
100
-
101
- # A Notification is a Request object without an "id" member.
102
- # The Server MUST NOT reply to a Notification, including those
103
- # that are within a batch request.
104
- response = nil if !request.has_key?('id')
105
-
106
- response
107
- end
108
-
109
- def error_response(error, request = nil)
110
- resp = {
111
- 'jsonrpc' => JSON_RPC_VERSION,
112
- 'error' => error.to_h,
113
- }
114
- if !!request && request.has_key?('id')
115
- resp['id'] = request['id']
116
- else
117
- resp['id'] = nil
118
- end
119
-
120
- resp
121
- end
122
-
123
- def success_response(request, result)
124
- {
125
- 'jsonrpc' => JSON_RPC_VERSION,
126
- 'result' => result,
127
- 'id' => request['id']
128
- }
129
- end
130
-
131
- def parse_request(post)
132
- data = JSON.parse(post)
133
- rescue
134
- raise Jimson::ServerError::ParseError.new
135
- end
136
-
137
- end
138
- end