rpcc.lua 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. -- Copyright 2009 Steven Barth <steven@midlink.org>
  2. -- Licensed to the public under the Apache License 2.0.
  3. local util = require "luci.util"
  4. local json = require "luci.json"
  5. local ltn12 = require "luci.ltn12"
  6. local nixio = require "nixio", require "nixio.util"
  7. local tostring, assert, setmetatable = tostring, assert, setmetatable
  8. local error = error
  9. module "luci.rpcc"
  10. RQLIMIT = 32 * nixio.const.buffersize
  11. Client = util.class()
  12. function Client.__init__(self, fd, v1)
  13. self.fd = fd
  14. self.uniqueid = tostring(self):match("0x([a-f0-9]+)")
  15. self.msgid = 1
  16. self.v1 = v1
  17. end
  18. function Client.request(self, method, params, notification)
  19. local oldchunk = self.decoder and self.decoder.chunk
  20. self.decoder = json.ActiveDecoder(self.fd:blocksource(nil, RQLIMIT))
  21. self.decoder.chunk = oldchunk
  22. local reqid = self.msgid .. self.uniqueid
  23. local reqdata = json.Encoder({
  24. id = (not notification) and (self.msgid .. self.uniqueid) or nil,
  25. jsonrpc = (not self.v1) and "2.0" or nil,
  26. method = method,
  27. params = params
  28. })
  29. ltn12.pump.all(reqdata:source(), self.fd:sink())
  30. if not notification then
  31. self.msgid = self.msgid + 1
  32. local response = self.decoder:get()
  33. assert(response.id == reqid, "Invalid response id")
  34. if response.error then
  35. error(response.error.message or response.error)
  36. end
  37. return response.result
  38. end
  39. end
  40. function Client.proxy(self, prefix)
  41. prefix = prefix or ""
  42. return setmetatable({}, {
  43. __call = function(proxy, ...)
  44. return self:request(prefix, {...})
  45. end,
  46. __index = function(proxy, name)
  47. return self:proxy(prefix .. name .. ".")
  48. end
  49. })
  50. end