GSoC: Documentation #2
This commit is contained in:
parent
f9263e00c1
commit
c47be2e727
12 changed files with 229 additions and 17 deletions
|
@ -17,6 +17,9 @@ local srv = require "luci.lucid.http.server"
|
||||||
|
|
||||||
module "luci.lucid.http"
|
module "luci.lucid.http"
|
||||||
|
|
||||||
|
--- Prepare the HTTP-daemon and its associated publishers.
|
||||||
|
-- @param publisher Table of publishers
|
||||||
|
-- @return factory callback or nil, error message
|
||||||
function factory(publisher)
|
function factory(publisher)
|
||||||
local server = srv.Server()
|
local server = srv.Server()
|
||||||
for _, r in ipairs(publisher) do
|
for _, r in ipairs(publisher) do
|
||||||
|
|
|
@ -18,6 +18,9 @@ local srv = require "luci.lucid.http.server"
|
||||||
module "luci.lucid.http.DirectoryPublisher"
|
module "luci.lucid.http.DirectoryPublisher"
|
||||||
|
|
||||||
|
|
||||||
|
--- Prepare a directory publisher and assign it to a given Virtual Host.
|
||||||
|
-- @param server HTTP daemon object
|
||||||
|
-- @param config publisher configuration
|
||||||
function factory(server, config)
|
function factory(server, config)
|
||||||
config.domain = config.domain or ""
|
config.domain = config.domain or ""
|
||||||
local vhost = server:get_vhosts()[config.domain]
|
local vhost = server:get_vhosts()[config.domain]
|
||||||
|
|
|
@ -18,6 +18,10 @@ local srv = require "luci.lucid.http.server"
|
||||||
|
|
||||||
module "luci.lucid.http.LuciWebPublisher"
|
module "luci.lucid.http.LuciWebPublisher"
|
||||||
|
|
||||||
|
|
||||||
|
--- Prepare a LuCI web publisher and assign it to a given Virtual Host.
|
||||||
|
-- @param server HTTP daemon object
|
||||||
|
-- @param config publisher configuration
|
||||||
function factory(server, config)
|
function factory(server, config)
|
||||||
pcall(function()
|
pcall(function()
|
||||||
require "luci.dispatcher"
|
require "luci.dispatcher"
|
||||||
|
|
|
@ -17,7 +17,9 @@ local srv = require "luci.lucid.http.server"
|
||||||
|
|
||||||
module "luci.lucid.http.Redirector"
|
module "luci.lucid.http.Redirector"
|
||||||
|
|
||||||
|
--- Prepare a redirector publisher and assign it to a given Virtual Host.
|
||||||
|
-- @param server HTTP daemon object
|
||||||
|
-- @param config publisher configuration
|
||||||
function factory(server, config)
|
function factory(server, config)
|
||||||
config.domain = config.domain or ""
|
config.domain = config.domain or ""
|
||||||
local vhost = server:get_vhosts()[config.domain]
|
local vhost = server:get_vhosts()[config.domain]
|
||||||
|
|
|
@ -15,8 +15,15 @@ local srv = require "luci.lucid.http.server"
|
||||||
local proto = require "luci.http.protocol"
|
local proto = require "luci.http.protocol"
|
||||||
local util = require "luci.util"
|
local util = require "luci.util"
|
||||||
|
|
||||||
|
--- Catchall Handler
|
||||||
|
-- @cstyle instance
|
||||||
module "luci.lucid.http.handler.catchall"
|
module "luci.lucid.http.handler.catchall"
|
||||||
|
|
||||||
|
--- Create a Redirect handler.
|
||||||
|
-- @param name Name
|
||||||
|
-- @param target Redirect Target
|
||||||
|
-- @class function
|
||||||
|
-- @return Redirect handler object
|
||||||
Redirect = util.class(srv.Handler)
|
Redirect = util.class(srv.Handler)
|
||||||
|
|
||||||
function Redirect.__init__(self, name, target)
|
function Redirect.__init__(self, name, target)
|
||||||
|
@ -24,6 +31,9 @@ function Redirect.__init__(self, name, target)
|
||||||
self.target = target
|
self.target = target
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Handle a GET request.
|
||||||
|
-- @param request Request object
|
||||||
|
-- @return status code, header table, response source
|
||||||
function Redirect.handle_GET(self, request)
|
function Redirect.handle_GET(self, request)
|
||||||
local target = self.target
|
local target = self.target
|
||||||
local protocol = request.env.HTTPS and "https://" or "http://"
|
local protocol = request.env.HTTPS and "https://" or "http://"
|
||||||
|
@ -46,8 +56,16 @@ function Redirect.handle_GET(self, request)
|
||||||
return 302, { Location = target }
|
return 302, { Location = target }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Handle a POST request.
|
||||||
|
-- @class function
|
||||||
|
-- @param request Request object
|
||||||
|
-- @return status code, header table, response source
|
||||||
Redirect.handle_POST = Redirect.handle_GET
|
Redirect.handle_POST = Redirect.handle_GET
|
||||||
|
|
||||||
|
--- Handle a HEAD request.
|
||||||
|
-- @class function
|
||||||
|
-- @param request Request object
|
||||||
|
-- @return status code, header table, response source
|
||||||
function Redirect.handle_HEAD(self, request)
|
function Redirect.handle_HEAD(self, request)
|
||||||
local stat, head = self:handle_GET(request)
|
local stat, head = self:handle_GET(request)
|
||||||
return stat, head
|
return stat, head
|
||||||
|
|
|
@ -28,8 +28,16 @@ local date = require "luci.http.protocol.date"
|
||||||
local mime = require "luci.http.protocol.mime"
|
local mime = require "luci.http.protocol.mime"
|
||||||
local cond = require "luci.http.protocol.conditionals"
|
local cond = require "luci.http.protocol.conditionals"
|
||||||
|
|
||||||
|
--- File system handler
|
||||||
|
-- @cstyle instance
|
||||||
module "luci.lucid.http.handler.file"
|
module "luci.lucid.http.handler.file"
|
||||||
|
|
||||||
|
--- Create a simple file system handler.
|
||||||
|
-- @class function
|
||||||
|
-- @param name Name
|
||||||
|
-- @param docroot Physical Document Root
|
||||||
|
-- @param options Options
|
||||||
|
-- @return Simple file system handler object
|
||||||
Simple = util.class(srv.Handler)
|
Simple = util.class(srv.Handler)
|
||||||
|
|
||||||
function Simple.__init__(self, name, docroot, options)
|
function Simple.__init__(self, name, docroot, options)
|
||||||
|
@ -42,6 +50,10 @@ function Simple.__init__(self, name, docroot, options)
|
||||||
self.error404 = options.error404
|
self.error404 = options.error404
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Parse a range request.
|
||||||
|
-- @param request Request object
|
||||||
|
-- @param size File size
|
||||||
|
-- @return offset, length, range header or boolean status
|
||||||
function Simple.parse_range(self, request, size)
|
function Simple.parse_range(self, request, size)
|
||||||
if not request.headers.Range then
|
if not request.headers.Range then
|
||||||
return true
|
return true
|
||||||
|
@ -75,6 +87,9 @@ function Simple.parse_range(self, request, size)
|
||||||
return from, (1 + to - from), range
|
return from, (1 + to - from), range
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Translate path and return file information.
|
||||||
|
-- @param uri Request URI
|
||||||
|
-- @return physical file path, file information
|
||||||
function Simple.getfile(self, uri)
|
function Simple.getfile(self, uri)
|
||||||
if not self.realdocroot then
|
if not self.realdocroot then
|
||||||
self.realdocroot = fs.realpath(self.docroot)
|
self.realdocroot = fs.realpath(self.docroot)
|
||||||
|
@ -86,6 +101,9 @@ function Simple.getfile(self, uri)
|
||||||
return file, fs.stat(file)
|
return file, fs.stat(file)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Handle a GET request.
|
||||||
|
-- @param request Request object
|
||||||
|
-- @return status code, header table, response source
|
||||||
function Simple.handle_GET(self, request)
|
function Simple.handle_GET(self, request)
|
||||||
local file, stat = self:getfile(prot.urldecode(request.env.PATH_INFO, true))
|
local file, stat = self:getfile(prot.urldecode(request.env.PATH_INFO, true))
|
||||||
|
|
||||||
|
@ -190,7 +208,7 @@ function Simple.handle_GET(self, request)
|
||||||
'p { margin:0 }' ..
|
'p { margin:0 }' ..
|
||||||
'\n</style></head><body><h1>Index of %s/</h1><hr /><ul>'..
|
'\n</style></head><body><h1>Index of %s/</h1><hr /><ul>'..
|
||||||
'<li><p><a href="%s/../">../</a> ' ..
|
'<li><p><a href="%s/../">../</a> ' ..
|
||||||
'<small>(parent directory)</small><br />' ..
|
'<small>(parent directory)</small><br />' ..
|
||||||
'<small></small></li>',
|
'<small></small></li>',
|
||||||
duri, duri, ruri
|
duri, duri, ruri
|
||||||
)
|
)
|
||||||
|
@ -244,6 +262,9 @@ function Simple.handle_GET(self, request)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Handle a HEAD request.
|
||||||
|
-- @param request Request object
|
||||||
|
-- @return status code, header table, response source
|
||||||
function Simple.handle_HEAD(self, ...)
|
function Simple.handle_HEAD(self, ...)
|
||||||
local stat, head = self:handle_GET(...)
|
local stat, head = self:handle_GET(...)
|
||||||
return stat, head
|
return stat, head
|
||||||
|
|
|
@ -19,8 +19,15 @@ local srv = require "luci.lucid.http.server"
|
||||||
local coroutine = require "coroutine"
|
local coroutine = require "coroutine"
|
||||||
local type = type
|
local type = type
|
||||||
|
|
||||||
|
--- LuCI web handler
|
||||||
|
-- @cstyle instance
|
||||||
module "luci.lucid.http.handler.luci"
|
module "luci.lucid.http.handler.luci"
|
||||||
|
|
||||||
|
--- Create a LuCI web handler.
|
||||||
|
-- @class function
|
||||||
|
-- @param name Name
|
||||||
|
-- @param prefix Dispatching prefix
|
||||||
|
-- @return LuCI web handler object
|
||||||
Luci = util.class(srv.Handler)
|
Luci = util.class(srv.Handler)
|
||||||
|
|
||||||
function Luci.__init__(self, name, prefix)
|
function Luci.__init__(self, name, prefix)
|
||||||
|
@ -28,15 +35,24 @@ function Luci.__init__(self, name, prefix)
|
||||||
self.prefix = prefix
|
self.prefix = prefix
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Handle a HEAD request.
|
||||||
|
-- @param request Request object
|
||||||
|
-- @return status code, header table, response source
|
||||||
function Luci.handle_HEAD(self, ...)
|
function Luci.handle_HEAD(self, ...)
|
||||||
local stat, head = self:handle_GET(...)
|
local stat, head = self:handle_GET(...)
|
||||||
return stat, head
|
return stat, head
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Handle a POST request.
|
||||||
|
-- @param request Request object
|
||||||
|
-- @return status code, header table, response source
|
||||||
function Luci.handle_POST(self, ...)
|
function Luci.handle_POST(self, ...)
|
||||||
return self:handle_GET(...)
|
return self:handle_GET(...)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Handle a GET request.
|
||||||
|
-- @param request Request object
|
||||||
|
-- @return status code, header table, response source
|
||||||
function Luci.handle_GET(self, request, sourcein)
|
function Luci.handle_GET(self, request, sourcein)
|
||||||
local r = http.Request(
|
local r = http.Request(
|
||||||
request.env,
|
request.env,
|
||||||
|
|
|
@ -23,6 +23,8 @@ local proto = require "luci.http.protocol"
|
||||||
local table = require "table"
|
local table = require "table"
|
||||||
local date = require "luci.http.protocol.date"
|
local date = require "luci.http.protocol.date"
|
||||||
|
|
||||||
|
--- HTTP Daemon
|
||||||
|
-- @cstyle instance
|
||||||
module "luci.lucid.http.server"
|
module "luci.lucid.http.server"
|
||||||
|
|
||||||
VERSION = "1.0"
|
VERSION = "1.0"
|
||||||
|
@ -46,7 +48,11 @@ statusmsg = {
|
||||||
[503] = "Server Unavailable",
|
[503] = "Server Unavailable",
|
||||||
}
|
}
|
||||||
|
|
||||||
-- File Resource
|
--- Create a new IO resource response.
|
||||||
|
-- @class function
|
||||||
|
-- @param fd File descriptor
|
||||||
|
-- @param len Length of data
|
||||||
|
-- @return IO resource
|
||||||
IOResource = util.class()
|
IOResource = util.class()
|
||||||
|
|
||||||
function IOResource.__init__(self, fd, len)
|
function IOResource.__init__(self, fd, len)
|
||||||
|
@ -54,19 +60,26 @@ function IOResource.__init__(self, fd, len)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Server handler implementation
|
--- Create a server handler.
|
||||||
|
-- @class function
|
||||||
|
-- @param name Name
|
||||||
|
-- @return Handler
|
||||||
Handler = util.class()
|
Handler = util.class()
|
||||||
|
|
||||||
function Handler.__init__(self, name)
|
function Handler.__init__(self, name)
|
||||||
self.name = name or tostring(self)
|
self.name = name or tostring(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Creates a failure reply
|
--- Create a failure reply.
|
||||||
|
-- @param code HTTP status code
|
||||||
|
-- @param msg Status message
|
||||||
|
-- @return status code, header table, response source
|
||||||
function Handler.failure(self, code, msg)
|
function Handler.failure(self, code, msg)
|
||||||
return code, { ["Content-Type"] = "text/plain" }, ltn12.source.string(msg)
|
return code, { ["Content-Type"] = "text/plain" }, ltn12.source.string(msg)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Access Restrictions
|
--- Add an access restriction.
|
||||||
|
-- @param restriction Restriction specification
|
||||||
function Handler.restrict(self, restriction)
|
function Handler.restrict(self, restriction)
|
||||||
if not self.restrictions then
|
if not self.restrictions then
|
||||||
self.restrictions = {restriction}
|
self.restrictions = {restriction}
|
||||||
|
@ -75,7 +88,9 @@ function Handler.restrict(self, restriction)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check restrictions
|
--- Enforce access restrictions.
|
||||||
|
-- @param request Request object
|
||||||
|
-- @return nil or HTTP statuscode, table of headers, response source
|
||||||
function Handler.checkrestricted(self, request)
|
function Handler.checkrestricted(self, request)
|
||||||
if not self.restrictions then
|
if not self.restrictions then
|
||||||
return
|
return
|
||||||
|
@ -126,7 +141,10 @@ function Handler.checkrestricted(self, request)
|
||||||
}, ltn12.source.string("Unauthorized")
|
}, ltn12.source.string("Unauthorized")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Processes a request
|
--- Process a request.
|
||||||
|
-- @param request Request object
|
||||||
|
-- @param sourcein Request data source
|
||||||
|
-- @return HTTP statuscode, table of headers, response source
|
||||||
function Handler.process(self, request, sourcein)
|
function Handler.process(self, request, sourcein)
|
||||||
local stat, code, hdr, sourceout
|
local stat, code, hdr, sourceout
|
||||||
|
|
||||||
|
@ -153,12 +171,19 @@ function Handler.process(self, request, sourcein)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Create a Virtual Host.
|
||||||
|
-- @class function
|
||||||
|
-- @return Virtual Host
|
||||||
VHost = util.class()
|
VHost = util.class()
|
||||||
|
|
||||||
function VHost.__init__(self)
|
function VHost.__init__(self)
|
||||||
self.handlers = {}
|
self.handlers = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Process a request and invoke the appropriate handler.
|
||||||
|
-- @param request Request object
|
||||||
|
-- @param ... Additional parameters passed to the handler
|
||||||
|
-- @return HTTP statuscode, table of headers, response source
|
||||||
function VHost.process(self, request, ...)
|
function VHost.process(self, request, ...)
|
||||||
local handler
|
local handler
|
||||||
local hlen = -1
|
local hlen = -1
|
||||||
|
@ -189,15 +214,20 @@ function VHost.process(self, request, ...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get a list of registered handlers.
|
||||||
|
-- @return Table of handlers
|
||||||
function VHost.get_handlers(self)
|
function VHost.get_handlers(self)
|
||||||
return self.handlers
|
return self.handlers
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Register handler with a given URI prefix.
|
||||||
|
-- @oaram match URI prefix
|
||||||
|
-- @param handler Handler object
|
||||||
function VHost.set_handler(self, match, handler)
|
function VHost.set_handler(self, match, handler)
|
||||||
self.handlers[match] = handler
|
self.handlers[match] = handler
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Remap IPv6-IPv4-compatibility addresses back to IPv4 addresses.
|
||||||
local function remapipv6(adr)
|
local function remapipv6(adr)
|
||||||
local map = "::ffff:"
|
local map = "::ffff:"
|
||||||
if adr:sub(1, #map) == map then
|
if adr:sub(1, #map) == map then
|
||||||
|
@ -207,6 +237,7 @@ local function remapipv6(adr)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Create a source that decodes chunked-encoded data from a socket.
|
||||||
local function chunksource(sock, buffer)
|
local function chunksource(sock, buffer)
|
||||||
buffer = buffer or ""
|
buffer = buffer or ""
|
||||||
return function()
|
return function()
|
||||||
|
@ -250,6 +281,7 @@ local function chunksource(sock, buffer)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Create a sink that chunk-encodes data and writes it on a given socket.
|
||||||
local function chunksink(sock)
|
local function chunksink(sock)
|
||||||
return function(chunk, err)
|
return function(chunk, err)
|
||||||
if not chunk then
|
if not chunk then
|
||||||
|
@ -260,20 +292,33 @@ local function chunksink(sock)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Create a server object.
|
||||||
|
-- @class function
|
||||||
|
-- @return Server object
|
||||||
Server = util.class()
|
Server = util.class()
|
||||||
|
|
||||||
function Server.__init__(self)
|
function Server.__init__(self)
|
||||||
self.vhosts = {}
|
self.vhosts = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get a list of registered virtual hosts.
|
||||||
|
-- @return Table of virtual hosts
|
||||||
function Server.get_vhosts(self)
|
function Server.get_vhosts(self)
|
||||||
return self.vhosts
|
return self.vhosts
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Register a virtual host with a given name.
|
||||||
|
-- @param name Hostname
|
||||||
|
-- @param vhost Virtual host object
|
||||||
function Server.set_vhost(self, name, vhost)
|
function Server.set_vhost(self, name, vhost)
|
||||||
self.vhosts[name] = vhost
|
self.vhosts[name] = vhost
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Send a fatal error message to given client and close the connection.
|
||||||
|
-- @param client Client socket
|
||||||
|
-- @param code HTTP status code
|
||||||
|
-- @param msg status message
|
||||||
function Server.error(self, client, code, msg)
|
function Server.error(self, client, code, msg)
|
||||||
hcode = tostring(code)
|
hcode = tostring(code)
|
||||||
|
|
||||||
|
@ -304,6 +349,9 @@ local hdr2env = {
|
||||||
["User-Agent"] = "HTTP_USER_AGENT"
|
["User-Agent"] = "HTTP_USER_AGENT"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--- Parse the request headers and prepare the environment.
|
||||||
|
-- @param source line-based input source
|
||||||
|
-- @return Request object
|
||||||
function Server.parse_headers(self, source)
|
function Server.parse_headers(self, source)
|
||||||
local env = {}
|
local env = {}
|
||||||
local req = {env = env, headers = {}}
|
local req = {env = env, headers = {}}
|
||||||
|
@ -348,7 +396,9 @@ function Server.parse_headers(self, source)
|
||||||
return req
|
return req
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Handle a new client connection.
|
||||||
|
-- @param client client socket
|
||||||
|
-- @param env superserver environment
|
||||||
function Server.process(self, client, env)
|
function Server.process(self, client, env)
|
||||||
local sourcein = function() end
|
local sourcein = function() end
|
||||||
local sourcehdr = client:linesource()
|
local sourcehdr = client:linesource()
|
||||||
|
|
|
@ -17,7 +17,9 @@ local srv = require "luci.lucid.rpc.server"
|
||||||
|
|
||||||
module "luci.lucid.rpc"
|
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)
|
function factory(publisher)
|
||||||
local root = srv.Module()
|
local root = srv.Module()
|
||||||
local server = srv.Server(root)
|
local server = srv.Server(root)
|
||||||
|
|
|
@ -16,8 +16,10 @@ local error, type = error, type
|
||||||
local nixio = require "nixio"
|
local nixio = require "nixio"
|
||||||
local srv = require "luci.lucid.rpc.server"
|
local srv = require "luci.lucid.rpc.server"
|
||||||
|
|
||||||
|
--- Remote UCI functions.
|
||||||
module "luci.lucid.rpc.ruci"
|
module "luci.lucid.rpc.ruci"
|
||||||
|
|
||||||
|
-- Prepare the remote UCI functions.
|
||||||
function _factory()
|
function _factory()
|
||||||
local m = srv.Module("Remote UCI API")
|
local m = srv.Module("Remote UCI API")
|
||||||
|
|
||||||
|
@ -30,10 +32,12 @@ function _factory()
|
||||||
return m
|
return m
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Get the associate RUCI instance.
|
||||||
local function getinst(session, name)
|
local function getinst(session, name)
|
||||||
return session.ruci and session.ruci[name]
|
return session.ruci and session.ruci[name]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Set a new RUCI instance.
|
||||||
local function setinst(session, obj)
|
local function setinst(session, obj)
|
||||||
session.ruci = session.ruci or {}
|
session.ruci = session.ruci or {}
|
||||||
local name = tostring(obj):match("0x([a-z0-9]+)")
|
local name = tostring(obj):match("0x([a-z0-9]+)")
|
||||||
|
@ -41,6 +45,7 @@ local function setinst(session, obj)
|
||||||
return name
|
return name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local Cursor = getmetatable(uci.cursor())
|
local Cursor = getmetatable(uci.cursor())
|
||||||
|
|
||||||
for name, func in pairs(Cursor) do
|
for name, func in pairs(Cursor) do
|
||||||
|
@ -50,14 +55,28 @@ for name, func in pairs(Cursor) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Generate a new RUCI cursor.
|
||||||
|
-- @param session Session object
|
||||||
|
-- @param ... Parameters passed to the UCI constructor
|
||||||
|
-- @return RUCI instance
|
||||||
function cursor(session, ...)
|
function cursor(session, ...)
|
||||||
return setinst(session, uci.cursor(...))
|
return setinst(session, uci.cursor(...))
|
||||||
end
|
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, ...)
|
function cursor_state(session, ...)
|
||||||
return setinst(session, uci.cursor_state(...))
|
return setinst(session, uci.cursor_state(...))
|
||||||
end
|
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)
|
function foreach(session, inst, config, sectiontype)
|
||||||
local inst = getinst(session, inst)
|
local inst = getinst(session, inst)
|
||||||
local secs = {}
|
local secs = {}
|
||||||
|
|
|
@ -22,6 +22,8 @@ local util = require "luci.util"
|
||||||
local table = require "table"
|
local table = require "table"
|
||||||
local ltn12 = require "luci.ltn12"
|
local ltn12 = require "luci.ltn12"
|
||||||
|
|
||||||
|
--- RPC daemom.
|
||||||
|
-- @cstyle instance
|
||||||
module "luci.lucid.rpc.server"
|
module "luci.lucid.rpc.server"
|
||||||
|
|
||||||
RQLIMIT = 32 * nixio.const.buffersize
|
RQLIMIT = 32 * nixio.const.buffersize
|
||||||
|
@ -48,9 +50,18 @@ ERRMSG = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--- Create an RPC method wrapper.
|
||||||
|
-- @class function
|
||||||
|
-- @param method Lua function
|
||||||
|
-- @param description Method description
|
||||||
|
-- @return Wrapped RPC method
|
||||||
Method = util.class()
|
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(...)
|
function Method.extended(...)
|
||||||
local m = Method(...)
|
local m = Method(...)
|
||||||
m.call = m.xcall
|
m.call = m.xcall
|
||||||
|
@ -62,14 +73,26 @@ function Method.__init__(self, method, description)
|
||||||
self.method = method
|
self.method = method
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Extended call the associated function.
|
||||||
|
-- @param session Session storage
|
||||||
|
-- @param argv Request parameters
|
||||||
|
-- @return function call response
|
||||||
function Method.xcall(self, session, argv)
|
function Method.xcall(self, session, argv)
|
||||||
return self.method(session, unpack(argv))
|
return self.method(session, unpack(argv))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Standard call the associated function.
|
||||||
|
-- @param session Session storage
|
||||||
|
-- @param argv Request parameters
|
||||||
|
-- @return function call response
|
||||||
function Method.call(self, session, argv)
|
function Method.call(self, session, argv)
|
||||||
return self.method(unpack(argv))
|
return self.method(unpack(argv))
|
||||||
end
|
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)
|
function Method.process(self, session, request, argv)
|
||||||
local stat, result = pcall(self.call, self, session, argv)
|
local stat, result = pcall(self.call, self, session, argv)
|
||||||
|
|
||||||
|
@ -84,7 +107,7 @@ function Method.process(self, session, request, argv)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Remap IPv6-IPv4-compatibility addresses to IPv4 addresses
|
||||||
local function remapipv6(adr)
|
local function remapipv6(adr)
|
||||||
local map = "::ffff:"
|
local map = "::ffff:"
|
||||||
if adr:sub(1, #map) == map then
|
if adr:sub(1, #map) == map then
|
||||||
|
@ -94,6 +117,11 @@ local function remapipv6(adr)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Create an RPC module.
|
||||||
|
-- @class function
|
||||||
|
-- @param description Method description
|
||||||
|
-- @return RPC module
|
||||||
Module = util.class()
|
Module = util.class()
|
||||||
|
|
||||||
function Module.__init__(self, description)
|
function Module.__init__(self, description)
|
||||||
|
@ -101,11 +129,15 @@ function Module.__init__(self, description)
|
||||||
self.handler = {}
|
self.handler = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Add a handler.
|
||||||
|
-- @param k key
|
||||||
|
-- @param v handler
|
||||||
function Module.add(self, k, v)
|
function Module.add(self, k, v)
|
||||||
self.handler[k] = v
|
self.handler[k] = v
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Access Restrictions
|
--- Add an access restriction.
|
||||||
|
-- @param restriction Restriction specification
|
||||||
function Module.restrict(self, restriction)
|
function Module.restrict(self, restriction)
|
||||||
if not self.restrictions then
|
if not self.restrictions then
|
||||||
self.restrictions = {restriction}
|
self.restrictions = {restriction}
|
||||||
|
@ -114,7 +146,9 @@ function Module.restrict(self, restriction)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check restrictions
|
--- Enforce access restrictions.
|
||||||
|
-- @param request Request object
|
||||||
|
-- @return nil or HTTP statuscode, table of headers, response source
|
||||||
function Module.checkrestricted(self, session, request, argv)
|
function Module.checkrestricted(self, session, request, argv)
|
||||||
if not self.restrictions then
|
if not self.restrictions then
|
||||||
return
|
return
|
||||||
|
@ -149,6 +183,10 @@ function Module.checkrestricted(self, session, request, argv)
|
||||||
return {error={code=ERRNO_NOACCESS, message=ERRMSG[ERRNO_NOACCESS]}}
|
return {error={code=ERRNO_NOACCESS, message=ERRMSG[ERRNO_NOACCESS]}}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Register a handler, submodule or function.
|
||||||
|
-- @param m entity
|
||||||
|
-- @param descr description
|
||||||
|
-- @return Module (self)
|
||||||
function Module.register(self, m, descr)
|
function Module.register(self, m, descr)
|
||||||
descr = descr or {}
|
descr = descr or {}
|
||||||
for k, v in pairs(m) do
|
for k, v in pairs(m) do
|
||||||
|
@ -164,6 +202,11 @@ function Module.register(self, m, descr)
|
||||||
return self
|
return self
|
||||||
end
|
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)
|
function Module.process(self, session, request, argv)
|
||||||
local first, last = request:match("^([^.]+).?(.*)$")
|
local first, last = request:match("^([^.]+).?(.*)$")
|
||||||
|
|
||||||
|
@ -182,21 +225,34 @@ function Module.process(self, session, request, argv)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Create a server object.
|
||||||
|
-- @class function
|
||||||
|
-- @param root Root module
|
||||||
|
-- @return Server object
|
||||||
Server = util.class()
|
Server = util.class()
|
||||||
|
|
||||||
function Server.__init__(self, root)
|
function Server.__init__(self, root)
|
||||||
self.root = root
|
self.root = root
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get the associated root module.
|
||||||
|
-- @return Root module
|
||||||
function Server.get_root(self)
|
function Server.get_root(self)
|
||||||
return self.root
|
return self.root
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Set a new root module.
|
||||||
|
-- @param root Root module
|
||||||
function Server.set_root(self, root)
|
function Server.set_root(self, root)
|
||||||
self.root = root
|
self.root = root
|
||||||
end
|
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)
|
function Server.reply(self, jsonrpc, id, res, err)
|
||||||
id = id or json.null
|
id = id or json.null
|
||||||
|
|
||||||
|
@ -212,6 +268,9 @@ function Server.reply(self, jsonrpc, id, res, err)
|
||||||
):source()
|
):source()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Handle a new client connection.
|
||||||
|
-- @param client client socket
|
||||||
|
-- @param env superserver environment
|
||||||
function Server.process(self, client, env)
|
function Server.process(self, client, env)
|
||||||
local decoder
|
local decoder
|
||||||
local sinkout = client:sink()
|
local sinkout = client:sink()
|
||||||
|
|
|
@ -17,8 +17,10 @@ local srv = require "luci.lucid.rpc.server"
|
||||||
local nixio = require "nixio"
|
local nixio = require "nixio"
|
||||||
local lucid = require "luci.lucid"
|
local lucid = require "luci.lucid"
|
||||||
|
|
||||||
|
--- Internal system functions.
|
||||||
module "luci.lucid.rpc.system"
|
module "luci.lucid.rpc.system"
|
||||||
|
|
||||||
|
-- Prepare the RPC module.
|
||||||
function _factory()
|
function _factory()
|
||||||
local mod = srv.Module("System functions"):register({
|
local mod = srv.Module("System functions"):register({
|
||||||
echo = echo,
|
echo = echo,
|
||||||
|
@ -34,15 +36,22 @@ function _factory()
|
||||||
return mod
|
return mod
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Simple echo test function.
|
||||||
|
-- @param object to be echoed object
|
||||||
|
-- @return echo object
|
||||||
function echo(object)
|
function echo(object)
|
||||||
return object
|
return object
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Simple void test function.
|
||||||
function void()
|
function void()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Accumulate different requests and execute them.
|
||||||
|
-- @param session Session object
|
||||||
|
-- @param ...
|
||||||
|
-- @return overall response object
|
||||||
function multicall(session, ...)
|
function multicall(session, ...)
|
||||||
local server, responses, response = session.server, {}, nil
|
local server, responses, response = session.server, {}, nil
|
||||||
for k, req in ipairs({...}) do
|
for k, req in ipairs({...}) do
|
||||||
|
@ -69,6 +78,12 @@ function multicall(session, ...)
|
||||||
return responses
|
return responses
|
||||||
end
|
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)
|
function authenticate(session, type, entity, key)
|
||||||
if not type then
|
if not type then
|
||||||
session.user = nil
|
session.user = nil
|
||||||
|
|
Loading…
Reference in a new issue