Globally reduce copyright headers
[project/luci.git] / libs / luci-lib-rpcc / luasrc / rpcc.lua
1 -- Copyright 2009 Steven Barth <steven@midlink.org>
2 -- Licensed to the public under the Apache License 2.0.
3
4 local util = require "luci.util"
5 local json = require "luci.json"
6 local ltn12 = require "luci.ltn12"
7 local nixio = require "nixio", require "nixio.util"
8
9 local tostring, assert, setmetatable = tostring, assert, setmetatable
10 local error = error
11
12 --- LuCI RPC Client.
13 -- @cstyle instance
14 module "luci.rpcc"
15
16 RQLIMIT = 32 * nixio.const.buffersize
17
18 --- Create a new JSON-RPC stream client.
19 -- @class function
20 -- @param fd File descriptor
21 -- @param v1 Use protocol version 1.0
22 -- @return RPC Client
23 Client = util.class()
24
25 function Client.__init__(self, fd, v1)
26         self.fd = fd
27         self.uniqueid = tostring(self):match("0x([a-f0-9]+)")
28         self.msgid = 1
29         self.v1 = v1
30 end
31
32 --- Request an RP call and get the response.
33 -- @param method Remote method
34 -- @param params Parameters
35 -- @param notification Notification only?
36 -- @return response 
37 function Client.request(self, method, params, notification)
38         local oldchunk = self.decoder and self.decoder.chunk
39         self.decoder = json.ActiveDecoder(self.fd:blocksource(nil, RQLIMIT))
40         self.decoder.chunk = oldchunk
41         
42         local reqid = self.msgid .. self.uniqueid
43         local reqdata = json.Encoder({
44                 id = (not notification) and (self.msgid .. self.uniqueid) or nil,
45                 jsonrpc = (not self.v1) and "2.0" or nil,
46                 method = method,
47                 params = params
48         })
49         ltn12.pump.all(reqdata:source(), self.fd:sink())
50         if not notification then
51                 self.msgid = self.msgid + 1
52                 local response = self.decoder:get()
53                 assert(response.id == reqid, "Invalid response id")
54                 if response.error then
55                         error(response.error.message or response.error)
56                 end
57                 return response.result
58         end
59 end
60
61 --- Create a transparent RPC proxy.
62 -- @param prefix Method prefix
63 -- @return RPC Proxy object
64 function Client.proxy(self, prefix)
65         prefix = prefix or ""
66         return setmetatable({}, {
67                 __call = function(proxy, ...)
68                         return self:request(prefix, {...})
69                 end,
70                 __index = function(proxy, name)
71                         return self:proxy(prefix .. name .. ".")
72                 end
73         })
74 end