1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
module("luci.jsonrpc", package.seeall)
require "luci.json"
function resolve(mod, method)
local path = luci.util.split(method, ".")
for j=1, #path-1 do
if not type(mod) == "table" then
break
end
mod = rawget(mod, path[j])
if not mod then
break
end
end
mod = type(mod) == "table" and rawget(mod, path[#path]) or nil
if type(mod) == "function" then
return mod
end
end
function handle(tbl, rawsource, ...)
local decoder = luci.json.Decoder()
local stat = luci.ltn12.pump.all(rawsource, decoder:sink())
local json = decoder:get()
local response
local success = false
if stat then
if type(json.method) == "string"
and (not json.params or type(json.params) == "table") then
local method = resolve(tbl, json.method)
if method then
response = reply(json.jsonrpc, json.id,
proxy(method, unpack(json.params or {})))
else
response = reply(json.jsonrpc, json.id,
nil, {code=-32601, message="Method not found."})
end
else
response = reply(json.jsonrpc, json.id,
nil, {code=-32600, message="Invalid request."})
end
else
response = reply("2.0", nil,
nil, {code=-32700, message="Parse error."})
end
return luci.json.Encoder(response, ...):source()
end
function reply(jsonrpc, id, res, err)
require "luci.json"
id = id or luci.json.null
-- 1.0 compatibility
if jsonrpc ~= "2.0" then
jsonrpc = nil
res = res or luci.json.null
err = err or luci.json.null
end
return {id=id, result=res, error=err, jsonrpc=jsonrpc}
end
function proxy(method, ...)
local res = {luci.util.copcall(method, ...)}
local stat = table.remove(res, 1)
if not stat then
return nil, {code=-32602, message="Invalid params.", data=table.remove(res, 1)}
else
if #res <= 1 then
return res[1] or luci.json.null
else
return res
end
end
end
|