diff options
Diffstat (limited to 'libs/lucid-rpc')
-rw-r--r-- | libs/lucid-rpc/Makefile | 2 | ||||
-rw-r--r-- | libs/lucid-rpc/docs/OVERVIEW | 19 | ||||
-rw-r--r-- | libs/lucid-rpc/luasrc/lucid/rpc.lua | 51 | ||||
-rw-r--r-- | libs/lucid-rpc/luasrc/lucid/rpc/ruci.lua | 85 | ||||
-rw-r--r-- | libs/lucid-rpc/luasrc/lucid/rpc/server.lua | 338 | ||||
-rw-r--r-- | libs/lucid-rpc/luasrc/lucid/rpc/system.lua | 101 |
6 files changed, 0 insertions, 596 deletions
diff --git a/libs/lucid-rpc/Makefile b/libs/lucid-rpc/Makefile deleted file mode 100644 index f7fac7740..000000000 --- a/libs/lucid-rpc/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -include ../../build/config.mk -include ../../build/module.mk diff --git a/libs/lucid-rpc/docs/OVERVIEW b/libs/lucid-rpc/docs/OVERVIEW deleted file mode 100644 index 9da870065..000000000 --- a/libs/lucid-rpc/docs/OVERVIEW +++ /dev/null @@ -1,19 +0,0 @@ - LuCId JSON-RPC Server Slave - -*** Abstract *** -The LuCId JSON-RPC server slave implements the JSON-RPC 1.0 and 2.0 protocol -to allow efficient light-weight remote procedure calling. -It provides notification support and several unofficial protocol extensions such -as: - * Close notifications - * Raw TCP switching to transfer BLOBs efficiently - * Client notification - - -*** Workflow *** -After receiving an incoming connection from LuCId, the slave analyses the -request and passes it to the matching handler. The handler will enforce -access restriction and deserialize the payload data and invokes the assigned -Lua function in a protected way. In case of a success the handler will serialize -the response and send it to the client - otherwise a detailed error message -will be returned.
\ No newline at end of file diff --git a/libs/lucid-rpc/luasrc/lucid/rpc.lua b/libs/lucid-rpc/luasrc/lucid/rpc.lua deleted file mode 100644 index 417e57214..000000000 --- a/libs/lucid-rpc/luasrc/lucid/rpc.lua +++ /dev/null @@ -1,51 +0,0 @@ ---[[ -LuCI - Lua Development Framework - -Copyright 2009 Steven Barth <steven@midlink.org> - -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$ -]] - -local require, ipairs, pcall = require, ipairs, pcall -local srv = require "luci.lucid.rpc.server" - -module "luci.lucid.rpc" - ---- Prepare the RPC-daemon and its associated publishers. --- @param publisher Table of publishers --- @return factory callback or nil, error message -function factory(publisher) - local root = srv.Module() - local server = srv.Server(root) - - for _, r in ipairs(publisher) do - for _, m in ipairs(r.export) do - local s, mod = pcall(require, r.namespace .. "." .. m) - if s and mod then - local module = mod._factory() - - if r.exec then - for _, x in ipairs(r.exec) do - if x:sub(1,1) == ":" then - module:restrict({interface = x:sub(2)}) - else - module:restrict({user = x}) - end - end - end - - root:add(m, module) - else - return nil, mod - end - end - end - - return function(...) return server:process(...) end -end
\ No newline at end of file diff --git a/libs/lucid-rpc/luasrc/lucid/rpc/ruci.lua b/libs/lucid-rpc/luasrc/lucid/rpc/ruci.lua deleted file mode 100644 index f0910c7f0..000000000 --- a/libs/lucid-rpc/luasrc/lucid/rpc/ruci.lua +++ /dev/null @@ -1,85 +0,0 @@ ---[[ -LuCIRPCd -(c) 2009 Steven Barth <steven@midlink.org> - -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$ -]]-- -local uci = require "luci.model.uci" -local tostring, getmetatable, pairs = tostring, getmetatable, pairs -local error, type = error, type -local nixio = require "nixio" -local srv = require "luci.lucid.rpc.server" - ---- Remote UCI functions. -module "luci.lucid.rpc.ruci" - --- Prepare the remote UCI functions. -function _factory() - local m = srv.Module("Remote UCI API") - - for k, v in pairs(_M) do - if type(v) == "function" and v ~= _factory then - m:add(k, srv.Method.extended(v)) - end - end - - return m -end - --- Get the associate RUCI instance. -local function getinst(session, name) - return session.ruci and session.ruci[name] -end - --- Set a new RUCI instance. -local function setinst(session, obj) - session.ruci = session.ruci or {} - local name = tostring(obj):match("0x([a-z0-9]+)") - session.ruci[name] = obj - return name -end - - -local Cursor = getmetatable(uci.cursor()) - -for name, func in pairs(Cursor) do - _M[name] = function(session, inst, ...) - inst = getinst(session, inst) - return inst[name](inst, ...) - end -end - ---- Generate a new RUCI cursor. --- @param session Session object --- @param ... Parameters passed to the UCI constructor --- @return RUCI instance -function cursor(session, ...) - return setinst(session, uci.cursor(...)) -end - ---- Generate a new RUCI state cursor. --- @param session Session object --- @param ... Parameters passed to the UCI constructor --- @return RUCI instance -function cursor_state(session, ...) - return setinst(session, uci.cursor_state(...)) -end - ---- Custom foreach function. --- @param session Session object --- @param inst RUCI instance --- @param config UCI config --- @param sectiontype UCI sectiontype --- @return section data -function foreach(session, inst, config, sectiontype) - local inst = getinst(session, inst) - local secs = {} - inst:foreach(config, sectiontype, function(s) secs[#secs+1] = s end) - return secs -end
\ No newline at end of file diff --git a/libs/lucid-rpc/luasrc/lucid/rpc/server.lua b/libs/lucid-rpc/luasrc/lucid/rpc/server.lua deleted file mode 100644 index 18b004d8b..000000000 --- a/libs/lucid-rpc/luasrc/lucid/rpc/server.lua +++ /dev/null @@ -1,338 +0,0 @@ ---[[ -LuCI - Lua Development Framework - -Copyright 2009 Steven Barth <steven@midlink.org> - -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$ -]] - -local ipairs, pairs = ipairs, pairs -local tostring, tonumber = tostring, tonumber -local pcall, assert, type, unpack = pcall, assert, type, unpack - -local nixio = require "nixio" -local json = require "luci.json" -local util = require "luci.util" -local table = require "table" -local ltn12 = require "luci.ltn12" - ---- RPC daemom. --- @cstyle instance -module "luci.lucid.rpc.server" - -RQLIMIT = 32 * nixio.const.buffersize -VERSION = "1.0" - -ERRNO_PARSE = -32700 -ERRNO_INVALID = -32600 -ERRNO_UNKNOWN = -32001 -ERRNO_TIMEOUT = -32000 -ERRNO_NOTFOUND = -32601 -ERRNO_NOACCESS = -32002 -ERRNO_INTERNAL = -32603 -ERRNO_NOSUPPORT = -32003 - -ERRMSG = { - [ERRNO_PARSE] = "Parse error.", - [ERRNO_INVALID] = "Invalid request.", - [ERRNO_TIMEOUT] = "Connection timeout.", - [ERRNO_UNKNOWN] = "Unknown error.", - [ERRNO_NOTFOUND] = "Method not found.", - [ERRNO_NOACCESS] = "Access denied.", - [ERRNO_INTERNAL] = "Internal error.", - [ERRNO_NOSUPPORT] = "Operation not supported." -} - - ---- Create an RPC method wrapper. --- @class function --- @param method Lua function --- @param description Method description --- @return Wrapped RPC method -Method = util.class() - ---- Create an extended wrapped RPC method. --- @class function --- @param method Lua function --- @param description Method description --- @return Wrapped RPC method -function Method.extended(...) - local m = Method(...) - m.call = m.xcall - return m -end - -function Method.__init__(self, method, description) - self.description = description - self.method = method -end - ---- Extended call the associated function. --- @param session Session storage --- @param argv Request parameters --- @return function call response -function Method.xcall(self, session, argv) - return self.method(session, unpack(argv)) -end - ---- Standard call the associated function. --- @param session Session storage --- @param argv Request parameters --- @return function call response -function Method.call(self, session, argv) - return self.method(unpack(argv)) -end - ---- Process a given request and create a JSON response. --- @param session Session storage --- @param request Requested method --- @param argv Request parameters -function Method.process(self, session, request, argv) - local stat, result = pcall(self.call, self, session, argv) - - if stat then - return { result=result } - else - return { error={ - code=ERRNO_UNKNOWN, - message=ERRMSG[ERRNO_UNKNOWN], - data=result - } } - end -end - --- Remap IPv6-IPv4-compatibility addresses to IPv4 addresses -local function remapipv6(adr) - local map = "::ffff:" - if adr:sub(1, #map) == map then - return adr:sub(#map+1) - else - return adr - end -end - - ---- Create an RPC module. --- @class function --- @param description Method description --- @return RPC module -Module = util.class() - -function Module.__init__(self, description) - self.description = description - self.handler = {} -end - ---- Add a handler. --- @param k key --- @param v handler -function Module.add(self, k, v) - self.handler[k] = v -end - ---- Add an access restriction. --- @param restriction Restriction specification -function Module.restrict(self, restriction) - if not self.restrictions then - self.restrictions = {restriction} - else - self.restrictions[#self.restrictions+1] = restriction - end -end - ---- Enforce access restrictions. --- @param request Request object --- @return nil or HTTP statuscode, table of headers, response source -function Module.checkrestricted(self, session, request, argv) - if not self.restrictions then - return - end - - for _, r in ipairs(self.restrictions) do - local stat = true - if stat and r.interface then -- Interface restriction - if not session.localif then - for _, v in ipairs(session.env.interfaces) do - if v.addr == session.localaddr then - session.localif = v.name - break - end - end - end - - if r.interface ~= session.localif then - stat = false - end - end - - if stat and r.user and session.user ~= r.user then -- User restriction - stat = false - end - - if stat then - return - end - end - - return {error={code=ERRNO_NOACCESS, message=ERRMSG[ERRNO_NOACCESS]}} -end - ---- Register a handler, submodule or function. --- @param m entity --- @param descr description --- @return Module (self) -function Module.register(self, m, descr) - descr = descr or {} - for k, v in pairs(m) do - if util.instanceof(v, Method) then - self.handler[k] = v - elseif type(v) == "table" then - self.handler[k] = Module() - self.handler[k]:register(v, descr[k]) - elseif type(v) == "function" then - self.handler[k] = Method(v, descr[k]) - end - end - return self -end - ---- Process a request. --- @param session Session storage --- @param request Request object --- @param argv Request parameters --- @return JSON response object -function Module.process(self, session, request, argv) - local first, last = request:match("^([^.]+).?(.*)$") - - local stat = self:checkrestricted(session, request, argv) - if stat then -- Access Denied - return stat - end - - local hndl = first and self.handler[first] - if not hndl then - return {error={code=ERRNO_NOTFOUND, message=ERRMSG[ERRNO_NOTFOUND]}} - end - - session.chain[#session.chain+1] = self - return hndl:process(session, last, argv) -end - - ---- Create a server object. --- @class function --- @param root Root module --- @return Server object -Server = util.class() - -function Server.__init__(self, root) - self.root = root -end - ---- Get the associated root module. --- @return Root module -function Server.get_root(self) - return self.root -end - ---- Set a new root module. --- @param root Root module -function Server.set_root(self, root) - self.root = root -end - ---- Create a JSON reply. --- @param jsonrpc JSON-RPC version --- @param id Message id --- @param res Result --- @param err Error --- @reutrn JSON response source -function Server.reply(self, jsonrpc, id, res, err) - id = id or json.null - - -- 1.0 compatibility - if jsonrpc ~= "2.0" then - jsonrpc = nil - res = res or json.null - err = err or json.null - end - - return json.Encoder( - {id=id, result=res, error=err, jsonrpc=jsonrpc}, BUFSIZE - ):source() -end - ---- Handle a new client connection. --- @param client client socket --- @param env superserver environment -function Server.process(self, client, env) - local decoder - local sinkout = client:sink() - client:setopt("socket", "sndtimeo", 90) - client:setopt("socket", "rcvtimeo", 90) - - local close = false - local session = {server = self, chain = {}, client = client, env = env, - localaddr = remapipv6(client:getsockname())} - local req, stat, response, result, cb - - repeat - local oldchunk = decoder and decoder.chunk - decoder = json.ActiveDecoder(client:blocksource(nil, RQLIMIT)) - decoder.chunk = oldchunk - - result, response, cb = nil, nil, nil - - -- Read one request - stat, req = pcall(decoder.get, decoder) - - if stat then - if type(req) == "table" and type(req.method) == "string" - and (not req.params or type(req.params) == "table") then - req.params = req.params or {} - result, cb = self.root:process(session, req.method, req.params) - if type(result) == "table" then - if req.id ~= nil then - response = self:reply(req.jsonrpc, req.id, - result.result, result.error) - end - close = result.close - else - if req.id ~= nil then - response = self:reply(req.jsonrpc, req.id, nil, - {code=ERRNO_INTERNAL, message=ERRMSG[ERRNO_INTERNAL]}) - end - end - else - response = self:reply(req.jsonrpc, req.id, - nil, {code=ERRNO_INVALID, message=ERRMSG[ERRNO_INVALID]}) - end - else - if nixio.errno() ~= nixio.const.EAGAIN then - response = self:reply("2.0", nil, - nil, {code=ERRNO_PARSE, message=ERRMSG[ERRNO_PARSE]}) - --[[else - response = self:reply("2.0", nil, - nil, {code=ERRNO_TIMEOUT, message=ERRMSG_TIMEOUT})]] - end - close = true - end - - if response then - ltn12.pump.all(response, sinkout) - end - - if cb then - close = cb(client, session, self) or close - end - until close - - client:shutdown() - client:close() -end diff --git a/libs/lucid-rpc/luasrc/lucid/rpc/system.lua b/libs/lucid-rpc/luasrc/lucid/rpc/system.lua deleted file mode 100644 index cf3aa6abe..000000000 --- a/libs/lucid-rpc/luasrc/lucid/rpc/system.lua +++ /dev/null @@ -1,101 +0,0 @@ ---[[ -LuCI - Lua Development Framework - -Copyright 2009 Steven Barth <steven@midlink.org> - -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$ -]] - -local type, ipairs = type, ipairs -local srv = require "luci.lucid.rpc.server" -local nixio = require "nixio" -local lucid = require "luci.lucid" - ---- Internal system functions. -module "luci.lucid.rpc.system" - --- Prepare the RPC module. -function _factory() - local mod = srv.Module("System functions"):register({ - echo = echo, - void = void, - multicall = srv.Method.extended(multicall), - authenticate = srv.Method.extended(authenticate) - }) - mod.checkrestricted = function(self, session, request, ...) - if request ~= "authenticate" then - return srv.Module.checkrestricted(self, session, request, ...) - end - end - return mod -end - ---- Simple echo test function. --- @param object to be echoed object --- @return echo object -function echo(object) - return object -end - ---- Simple void test function. -function void() - -end - ---- Accumulate different requests and execute them. --- @param session Session object --- @param ... --- @return overall response object -function multicall(session, ...) - local server, responses, response = session.server, {}, nil - for k, req in ipairs({...}) do - response = nil - if type(req) == "table" and type(req.method) == "string" - and (not req.params or type(req.params) == "table") then - req.params = req.params or {} - result = server.root:process(session, req.method, req.params) - if type(result) == "table" then - if req.id ~= nil then - response = {jsonrpc=req.jsonrpc, id=req.id, - result=result.result, error=result.error} - end - else - if req.id ~= nil then - response = {jsonrpc=req.jsonrpc, id=req.id, - result=nil, error={code=srv.ERRNO_INTERNAL, - message=srv.ERRMSG[ERRNO_INTERNAL]}} - end - end - end - responses[k] = response - end - return responses -end - ---- Create or use a new authentication token. --- @param session Session object --- @param type Authentication type --- @param entity Authentication enttity (username) --- @param key Authentication key (password) --- @return boolean status -function authenticate(session, type, entity, key) - if not type then - session.user = nil - return true - elseif type == "plain" then - local pwe = nixio.getsp and nixio.getsp(entity) or nixio.getpw(entity) - local pwh = pwe and (pwe.pwdp or pwe.passwd) - if not pwh or #pwh < 1 or nixio.crypt(key, pwh) ~= pwh then - return nil - else - session.user = entity - return true - end - end -end
\ No newline at end of file |