class Sr::Jimson::Server
Constants
- JSON_RPC_VERSION
Attributes
host[RW]
opts[RW]
port[RW]
router[RW]
show_errors[RW]
Public Class Methods
new(router_or_handler, opts = {})
click to toggle source
router_or_handler
is an instance of Sr::Jimson::Router
or extends Sr::Jimson::Handler
opts
may include:
-
:host - the hostname or ip to bind to
-
:port - the port to listen on
-
:server - the rack handler to use, e.g. 'webrick' or 'thin'
-
:show_errors - true or false, send backtraces in error responses?
Remaining options are forwarded to the underlying Rack server.
# File lib/sr/jimson/server.rb, line 52 def initialize(router_or_handler, opts = {}) if !router_or_handler.is_a?(Router) # arg is a handler, wrap it in a Router @router = Router.new @router.root router_or_handler else # arg is a router @router = router_or_handler end @router.namespace 'system', System.new(@router) @host = opts.delete(:host) || '0.0.0.0' @port = opts.delete(:port) || 8999 @show_errors = opts.delete(:show_errors) || false @opts = opts end
with_routes(opts = {}, &block)
click to toggle source
Create a Server
with routes defined
# File lib/sr/jimson/server.rb, line 35 def self.with_routes(opts = {}, &block) router = Router.new router.send(:draw, &block) self.new(router, opts) end
Public Instance Methods
call(env)
click to toggle source
Entry point for Rack
# File lib/sr/jimson/server.rb, line 83 def call(env) req = Rack::Request.new(env) resp = Rack::Response.new return resp.finish if !req.post? resp.write process(req.body.read) resp.finish end
create_response(request)
click to toggle source
# File lib/sr/jimson/server.rb, line 154 def create_response(request) method = request['method'] params = request['params'] result = dispatch_request(method, params) response = success_response(request, result) # A Notification is a Request object without an "id" member. # The Server MUST NOT reply to a Notification, including those # that are within a batch request. response = nil if !request.has_key?('id') return response rescue Server::Error => e raise e rescue ArgumentError raise Server::Error::InvalidParams.new rescue Exception, StandardError => e raise Server::Error::ApplicationError.new(e, @show_errors) end
dispatch_request(method, params)
click to toggle source
# File lib/sr/jimson/server.rb, line 176 def dispatch_request(method, params) method_name = method.to_s handler = @router.handler_for_method(method_name) method_name = @router.strip_method_namespace(method_name) if handler.nil? \ || !handler.class.jimson_exposed_methods.include?(method_name) \ || !handler.respond_to?(method_name) raise Server::Error::MethodNotFound.new(method) end if params.nil? return handler.send(method_name) elsif params.is_a?(Hash) return handler.send(method_name, params) else return handler.send(method_name, *params) end end
error_response(error, request = nil)
click to toggle source
# File lib/sr/jimson/server.rb, line 196 def error_response(error, request = nil) resp = { 'jsonrpc' => JSON_RPC_VERSION, 'error' => error.to_h, } if !!request && request.has_key?('id') resp['id'] = request['id'] else resp['id'] = nil end resp end
handle_request(request)
click to toggle source
# File lib/sr/jimson/server.rb, line 115 def handle_request(request) response = nil begin if !validate_request(request) response = error_response(Server::Error::InvalidRequest.new) else response = create_response(request) end rescue Server::Error => e response = error_response(e, request) end response end
parse_request(post)
click to toggle source
# File lib/sr/jimson/server.rb, line 218 def parse_request(post) MultiJson.decode(post) rescue raise Server::Error::ParseError.new end
process(content)
click to toggle source
# File lib/sr/jimson/server.rb, line 91 def process(content) begin request = parse_request(content) if request.is_a?(Array) raise Server::Error::InvalidRequest.new if request.empty? response = request.map { |req| handle_request(req) } else response = handle_request(request) end rescue Server::Error::ParseError, Server::Error::InvalidRequest => e response = error_response(e) rescue Server::Error => e response = error_response(e, request) rescue StandardError, Exception => e response = error_response(Server::Error::InternalError.new(e)) end response.compact! if response.is_a?(Array) return nil if response.nil? || (response.respond_to?(:empty?) && response.empty?) MultiJson.encode(response) end
start()
click to toggle source
Starts the server so it can process requests
# File lib/sr/jimson/server.rb, line 72 def start Rack::Server.start(opts.merge( :app => self, :Host => @host, :Port => @port )) end
success_response(request, result)
click to toggle source
# File lib/sr/jimson/server.rb, line 210 def success_response(request, result) { 'jsonrpc' => JSON_RPC_VERSION, 'result' => result, 'id' => request['id'] } end
validate_request(request)
click to toggle source
# File lib/sr/jimson/server.rb, line 130 def validate_request(request) required_keys = %w(jsonrpc method) required_types = { 'jsonrpc' => [String], 'method' => [String], 'params' => [Hash, Array], 'id' => [String, Fixnum, Bignum, NilClass] } return false if !request.is_a?(Hash) required_keys.each do |key| return false if !request.has_key?(key) end required_types.each do |key, types| return false if request.has_key?(key) && !types.any? { |type| request[key].is_a?(type) } end return false if request['jsonrpc'] != JSON_RPC_VERSION true end