Module: JsonRpc::Rpc

Defined in:
lib/json-rpc.rb

Defined Under Namespace

Classes: AsyncResult, Error

Constant Summary collapse

Version =
"2.0".freeze
Prefix =
"rpc_".freeze
ContentType =
"application/json".freeze
ErrorProtocol =
{
  :parse_error      => [500, -32700, "Parse error"],
  :invalid_request  => [400, -32600, "Invalid Request"],
  :method_not_found => [404, -32601, "Method not found"],
  :invalid_params   => [500, -32602, "Invalid params"],
  :internal_error   => [500, -32603, "Internal error"],
}

Class Method Summary collapse

Class Method Details

.error(index, id = nil, debug_msg = nil) ⇒ Object



73
74
75
76
77
78
# File 'lib/json-rpc.rb', line 73

def self.error index, id = nil, debug_msg = nil
  id = nil unless id.is_a? Fixnum
  ex = Rpc::Error.new *ErrorProtocol[index], debug_msg
  ex.id = id
  ex
end

.forge_response(result, id = nil) ⇒ Object



122
123
124
# File 'lib/json-rpc.rb', line 122

def self.forge_response result, id = nil
  {"jsonrpc" => Version, "id" => id.to_i, "result" => result}.to_json
end

.parse(env) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/json-rpc.rb', line 87

def self.parse env
  begin
    case env["REQUEST_METHOD"]
    when "POST"
      JSON.parse(env["rack.input"].read)
    when /^(GET|HEAD)$/
      req = Rack::Request.new(env)
      obj = req.params
      obj["id"] = obj["id"].to_i
      obj["params"] = obj["params"] ? JSON::parse(obj["params"]) : []
      obj
    else
      raise error :invalid_request, nil, "unsupported method #{env["REQUEST_METHOD"]} params: #{obj.inspect}"
    end

  rescue JSON::ParserError => e
    raise error :parse_error, nil, "JSON parsing error: #{e}"
  end
end

.route(request, ctrl) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/json-rpc.rb', line 107

def self.route request, ctrl
  method, params = Prefix + request["method"], request["params"]

  unless ctrl.respond_to? method
    raise error :method_not_found, request["id"], "method `#{method}` not found"
  end

  result = ctrl.send(method, *params)
  if result.is_a? AsyncResult
    result.id = request["id"]
    return result
  end
  forge_response result, request["id"]
end

.validate(request) ⇒ Object



80
81
82
83
84
85
# File 'lib/json-rpc.rb', line 80

def self.validate request
  return 200 if request["jsonrpc"] == Version and
    request["method"].kind_of?(String) and
    request["method"] != ""
  raise error :invalid_request, request["id"], "invalid request: #{request.inspect}"
end