General optimizations, simplifications and improvements
This commit is contained in:
parent
5cfda95377
commit
ffd5c4ec65
4 changed files with 138 additions and 129 deletions
|
@ -24,8 +24,21 @@ limitations under the License.
|
|||
|
||||
]]--
|
||||
|
||||
local io = require "io"
|
||||
local table = require "table"
|
||||
local debug = require "debug"
|
||||
local string = require "string"
|
||||
local coroutine = require "coroutine"
|
||||
|
||||
local getmetatable, setmetatable = getmetatable, setmetatable
|
||||
local getfenv, setfenv = getfenv, setfenv
|
||||
local rawget, rawset, unpack = rawget, rawset, unpack
|
||||
local tostring, type, assert = tostring, type, assert
|
||||
local ipairs, pairs, loadstring = ipairs, pairs, loadstring
|
||||
local require, pcall, xpcall = require, pcall, xpcall
|
||||
|
||||
--- LuCI utility functions.
|
||||
module("luci.util", package.seeall)
|
||||
module "luci.util"
|
||||
|
||||
--
|
||||
-- Pythonic string formatting extension
|
||||
|
@ -63,14 +76,10 @@ function class(base)
|
|||
local class = {}
|
||||
|
||||
local create = function(class, ...)
|
||||
local inst = {}
|
||||
setmetatable(inst, {__index = class})
|
||||
local inst = setmetatable({}, {__index = class})
|
||||
|
||||
if inst.__init__ then
|
||||
local stat, err = copcall(inst.__init__, inst, ...)
|
||||
if not stat then
|
||||
error(err)
|
||||
end
|
||||
inst:__init__(...)
|
||||
end
|
||||
|
||||
return inst
|
||||
|
@ -284,8 +293,7 @@ end
|
|||
-- @param str String value containing whitespace padded data
|
||||
-- @return String value with leading and trailing space removed
|
||||
function trim(str)
|
||||
local s = str:gsub("^%s*(.-)%s*$", "%1")
|
||||
return s
|
||||
return (str:gsub("^%s*(.-)%s*$", "%1"))
|
||||
end
|
||||
|
||||
--- Parse certain units from the given string and return the canonical integer
|
||||
|
@ -413,9 +421,7 @@ function clone(object, deep)
|
|||
copy[k] = v
|
||||
end
|
||||
|
||||
setmetatable(copy, getmetatable(object))
|
||||
|
||||
return copy
|
||||
return setmetatable(copy, getmetatable(object))
|
||||
end
|
||||
|
||||
|
||||
|
@ -473,11 +479,11 @@ function serialize_data(val, seen)
|
|||
elseif type(val) == "number" then
|
||||
return val
|
||||
elseif type(val) == "string" then
|
||||
return string.format("%q", val)
|
||||
return "%q" % val
|
||||
elseif type(val) == "boolean" then
|
||||
return val and "true" or "false"
|
||||
elseif type(val) == "function" then
|
||||
return string.format("loadstring(%q)", get_bytecode(val))
|
||||
return "loadstring(%q)" % get_bytecode(val)
|
||||
elseif type(val) == "table" then
|
||||
return "{ " .. _serialize_table(val, seen) .. " }"
|
||||
else
|
||||
|
@ -691,7 +697,7 @@ end
|
|||
--- Returns the absolute path to LuCI base directory.
|
||||
-- @return String containing the directory path
|
||||
function libpath()
|
||||
return luci.fs.dirname(require("luci.debug").__file__)
|
||||
return require "luci.fs".dirname(require "luci.debug".__file__)
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -25,13 +25,13 @@ limitations under the License.
|
|||
]]--
|
||||
|
||||
--- LuCI web dispatcher.
|
||||
module("luci.dispatcher", package.seeall)
|
||||
require("luci.util")
|
||||
require("luci.init")
|
||||
require("luci.http")
|
||||
require("luci.sys")
|
||||
require("luci.fs")
|
||||
local fs = require "luci.fs"
|
||||
local sys = require "luci.sys"
|
||||
local init = require "luci.init"
|
||||
local util = require "luci.util"
|
||||
local http = require "luci.http"
|
||||
|
||||
module("luci.dispatcher", package.seeall)
|
||||
context = luci.util.threadlocal()
|
||||
|
||||
authenticator = {}
|
||||
|
@ -106,23 +106,28 @@ function httpdispatch(request)
|
|||
table.insert(context.request, node)
|
||||
end
|
||||
|
||||
dispatch(context.request)
|
||||
local stat, err = util.copcall(dispatch, context.request)
|
||||
if not stat then
|
||||
error500(err)
|
||||
end
|
||||
|
||||
luci.http.close()
|
||||
end
|
||||
|
||||
--- Dispatches a LuCI virtual path.
|
||||
-- @param request Virtual path
|
||||
function dispatch(request)
|
||||
context.path = request
|
||||
local ctx = context
|
||||
ctx.path = request
|
||||
|
||||
require("luci.i18n")
|
||||
luci.i18n.setlanguage(require("luci.config").main.lang)
|
||||
require "luci.i18n".setlanguage(require "luci.config".main.lang)
|
||||
|
||||
if not context.tree then
|
||||
createtree()
|
||||
local c = ctx.tree
|
||||
local stat
|
||||
if not c then
|
||||
c = createtree()
|
||||
end
|
||||
|
||||
local c = context.tree
|
||||
local track = {}
|
||||
local args = {}
|
||||
context.args = args
|
||||
|
@ -135,9 +140,7 @@ function dispatch(request)
|
|||
break
|
||||
end
|
||||
|
||||
for k, v in pairs(c) do
|
||||
track[k] = v
|
||||
end
|
||||
util.update(track, c)
|
||||
|
||||
if c.leaf then
|
||||
break
|
||||
|
@ -155,46 +158,44 @@ function dispatch(request)
|
|||
end
|
||||
|
||||
-- Init template engine
|
||||
local tpl = require("luci.template")
|
||||
local viewns = {}
|
||||
tpl.context.viewns = viewns
|
||||
viewns.write = luci.http.write
|
||||
viewns.translate = function(...) return require("luci.i18n").translate(...) end
|
||||
viewns.striptags = luci.util.striptags
|
||||
viewns.controller = luci.http.getenv("SCRIPT_NAME")
|
||||
viewns.media = luci.config.main.mediaurlbase
|
||||
viewns.resource = luci.config.main.resourcebase
|
||||
viewns.REQUEST_URI = (luci.http.getenv("SCRIPT_NAME") or "") .. (luci.http.getenv("PATH_INFO") or "")
|
||||
|
||||
if track.dependent then
|
||||
local stat, err = pcall(assert, not track.auto)
|
||||
if not stat then
|
||||
error500(err)
|
||||
return
|
||||
end
|
||||
if not track.notemplate then
|
||||
local tpl = require("luci.template")
|
||||
local viewns = {}
|
||||
tpl.context.viewns = viewns
|
||||
viewns.write = luci.http.write
|
||||
viewns.translate = function(...) return require("luci.i18n").translate(...) end
|
||||
viewns.striptags = util.striptags
|
||||
viewns.controller = luci.http.getenv("SCRIPT_NAME")
|
||||
viewns.media = luci.config.main.mediaurlbase
|
||||
viewns.resource = luci.config.main.resourcebase
|
||||
viewns.REQUEST_URI = (luci.http.getenv("SCRIPT_NAME") or "") .. (luci.http.getenv("PATH_INFO") or "")
|
||||
end
|
||||
|
||||
assert(not track.dependent or not track.auto, "Access Violation")
|
||||
|
||||
if track.sysauth then
|
||||
require("luci.sauth")
|
||||
local sauth = require "luci.sauth"
|
||||
|
||||
local authen = type(track.sysauth_authenticator) == "function"
|
||||
and track.sysauth_authenticator
|
||||
or authenticator[track.sysauth_authenticator]
|
||||
|
||||
local def = (type(track.sysauth) == "string") and track.sysauth
|
||||
local accs = def and {track.sysauth} or track.sysauth
|
||||
local sess = luci.http.getcookie("sysauth")
|
||||
sess = sess and sess:match("^[A-F0-9]+$")
|
||||
local user = luci.sauth.read(sess)
|
||||
local user = sauth.read(sess)
|
||||
|
||||
if not luci.util.contains(accs, user) then
|
||||
if not util.contains(accs, user) then
|
||||
if authen then
|
||||
local user, sess = authen(luci.sys.user.checkpasswd, accs, def)
|
||||
if not user or not luci.util.contains(accs, user) then
|
||||
if not user or not util.contains(accs, user) then
|
||||
return
|
||||
else
|
||||
local sid = sess or luci.sys.uniqueid(16)
|
||||
luci.http.header("Set-Cookie", "sysauth=" .. sid.."; path=/")
|
||||
if not sess then
|
||||
luci.sauth.write(sid, user)
|
||||
sauth.write(sid, user)
|
||||
end
|
||||
end
|
||||
else
|
||||
|
@ -214,15 +215,12 @@ function dispatch(request)
|
|||
|
||||
if c and type(c.target) == "function" then
|
||||
context.dispatched = c
|
||||
stat, mod = luci.util.copcall(require, c.module)
|
||||
if stat then
|
||||
luci.util.updfenv(c.target, mod)
|
||||
end
|
||||
|
||||
stat, err = luci.util.copcall(c.target, unpack(args))
|
||||
if not stat then
|
||||
error500(err)
|
||||
end
|
||||
util.copcall(function()
|
||||
util.updfenv(c.target, require(c.module))
|
||||
end)
|
||||
|
||||
c.target(unpack(args))
|
||||
else
|
||||
error404()
|
||||
end
|
||||
|
@ -262,50 +260,33 @@ end
|
|||
-- @param path Controller base directory
|
||||
-- @param suffix Controller file suffix
|
||||
function createindex_plain(path, suffix)
|
||||
if indexcache then
|
||||
local cachedate = fs.mtime(indexcache)
|
||||
if cachedate and cachedate > fs.mtime(path) then
|
||||
index = loadfile(indexcache)()
|
||||
return index
|
||||
end
|
||||
end
|
||||
|
||||
index = {}
|
||||
|
||||
local cache = nil
|
||||
|
||||
local controllers = luci.util.combine(
|
||||
local controllers = util.combine(
|
||||
luci.fs.glob(path .. "*" .. suffix) or {},
|
||||
luci.fs.glob(path .. "*/*" .. suffix) or {}
|
||||
)
|
||||
|
||||
if indexcache then
|
||||
cache = luci.fs.mtime(indexcache)
|
||||
|
||||
if not cache then
|
||||
luci.fs.mkdir(indexcache)
|
||||
luci.fs.chmod(indexcache, "a=,u=rwx")
|
||||
cache = luci.fs.mtime(indexcache)
|
||||
end
|
||||
end
|
||||
|
||||
for i,c in ipairs(controllers) do
|
||||
local module = "luci.controller." .. c:sub(#path+1, #c-#suffix):gsub("/", ".")
|
||||
local cachefile
|
||||
local stime
|
||||
local ctime
|
||||
local mod = require(module)
|
||||
local idx = mod.index
|
||||
|
||||
if cache then
|
||||
cachefile = indexcache .. "/" .. module
|
||||
stime = luci.fs.mtime(c) or 0
|
||||
ctime = luci.fs.mtime(cachefile) or 0
|
||||
if type(idx) == "function" then
|
||||
index[module] = idx
|
||||
end
|
||||
|
||||
if not cache or stime > ctime then
|
||||
stat, mod = luci.util.copcall(require, module)
|
||||
end
|
||||
|
||||
if stat and mod and type(mod.index) == "function" then
|
||||
index[module] = mod.index
|
||||
|
||||
if cache then
|
||||
luci.fs.writefile(cachefile, luci.util.get_bytecode(mod.index))
|
||||
end
|
||||
end
|
||||
else
|
||||
index[module] = loadfile(cachefile)
|
||||
end
|
||||
if indexcache then
|
||||
fs.writefile(indexcache, util.get_bytecode(index))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -316,14 +297,17 @@ function createtree()
|
|||
createindex()
|
||||
end
|
||||
|
||||
context.tree = {nodes={}}
|
||||
require("luci.i18n")
|
||||
|
||||
-- Load default translation
|
||||
luci.i18n.loadc("default")
|
||||
local ctx = context
|
||||
local tree = {nodes={}}
|
||||
|
||||
local scope = luci.util.clone(_G)
|
||||
for k,v in pairs(luci.dispatcher) do
|
||||
ctx.treecache = setmetatable({}, {__mode="v"})
|
||||
ctx.tree = tree
|
||||
|
||||
-- Load default translation
|
||||
require "luci.i18n".loadc("default")
|
||||
|
||||
local scope = setmetatable({}, {__index = _G})
|
||||
for k,v in pairs(_M) do
|
||||
if type(v) == "function" then
|
||||
scope[k] = v
|
||||
end
|
||||
|
@ -332,14 +316,10 @@ function createtree()
|
|||
for k, v in pairs(index) do
|
||||
scope._NAME = k
|
||||
setfenv(v, scope)
|
||||
|
||||
local stat, err = luci.util.copcall(v)
|
||||
if not stat then
|
||||
error500("createtree failed: " .. k .. ": " .. err)
|
||||
luci.http.close()
|
||||
os.exit(1)
|
||||
end
|
||||
v()
|
||||
end
|
||||
|
||||
return tree
|
||||
end
|
||||
|
||||
--- Clone a node of the dispatching tree to another position.
|
||||
|
@ -391,16 +371,7 @@ end
|
|||
-- @param ... Virtual path
|
||||
-- @return Dispatching tree node
|
||||
function node(...)
|
||||
local c = context.tree
|
||||
arg.n = nil
|
||||
|
||||
for k,v in ipairs(arg) do
|
||||
if not c.nodes[v] then
|
||||
c.nodes[v] = {nodes={}, auto=true}
|
||||
end
|
||||
|
||||
c = c.nodes[v]
|
||||
end
|
||||
local c = _create_node(arg)
|
||||
|
||||
c.module = getfenv(2)._NAME
|
||||
c.path = arg
|
||||
|
@ -409,6 +380,29 @@ function node(...)
|
|||
return c
|
||||
end
|
||||
|
||||
function _create_node(path, cache)
|
||||
if #path == 0 then
|
||||
return context.tree
|
||||
end
|
||||
|
||||
cache = cache or context.treecache
|
||||
local name = table.concat(path, ".")
|
||||
local c = cache[name]
|
||||
|
||||
if not c then
|
||||
local last = table.remove(path)
|
||||
c = _create_node(path, cache)
|
||||
|
||||
local new = {nodes={}, auto=true}
|
||||
c.nodes[last] = new
|
||||
cache[name] = new
|
||||
|
||||
return new
|
||||
else
|
||||
return c
|
||||
end
|
||||
end
|
||||
|
||||
-- Subdispatchers --
|
||||
|
||||
--- Create a redirect to another dispatching node.
|
||||
|
|
|
@ -24,15 +24,20 @@ limitations under the License.
|
|||
|
||||
]]--
|
||||
|
||||
local ltn12 = require "luci.ltn12"
|
||||
local proto = require "luci.http.protocol"
|
||||
local util = require "luci.util"
|
||||
local string = require "string"
|
||||
local coroutine = require "coroutine"
|
||||
|
||||
local pairs, tostring, error = pairs, tostring, error
|
||||
|
||||
--- LuCI Web Framework high-level HTTP functions.
|
||||
module("luci.http", package.seeall)
|
||||
local ltn12 = require("luci.ltn12")
|
||||
require("luci.http.protocol")
|
||||
require("luci.util")
|
||||
module "luci.http"
|
||||
|
||||
context = luci.util.threadlocal()
|
||||
context = util.threadlocal()
|
||||
|
||||
Request = luci.util.class()
|
||||
Request = util.class()
|
||||
function Request.__init__(self, env, sourcein, sinkerr)
|
||||
self.input = sourcein
|
||||
self.error = sinkerr
|
||||
|
@ -45,7 +50,7 @@ function Request.__init__(self, env, sourcein, sinkerr)
|
|||
self.message = {
|
||||
env = env,
|
||||
headers = {},
|
||||
params = luci.http.protocol.urldecode_params(env.QUERY_STRING or ""),
|
||||
params = protocol.urldecode_params(env.QUERY_STRING or ""),
|
||||
}
|
||||
|
||||
self.parsed_input = false
|
||||
|
@ -109,7 +114,7 @@ function Request.setfilehandler(self, callback)
|
|||
end
|
||||
|
||||
function Request._parse_input(self)
|
||||
luci.http.protocol.parse_message_body(
|
||||
protocol.parse_message_body(
|
||||
self.input,
|
||||
self.message,
|
||||
self.filehandler
|
||||
|
@ -277,10 +282,10 @@ end
|
|||
-- @param no_plus Don't decode + to " "
|
||||
-- @return URL-decoded string
|
||||
-- @see urlencode
|
||||
urldecode = luci.http.protocol.urldecode
|
||||
urldecode = protocol.urldecode
|
||||
|
||||
--- Return the URL-encoded equivalent of a string.
|
||||
-- @param str Source string
|
||||
-- @return URL-encoded string
|
||||
-- @see urldecode
|
||||
urlencode = luci.http.protocol.urlencode
|
||||
urlencode = protocol.urlencode
|
||||
|
|
|
@ -36,20 +36,24 @@ function index()
|
|||
uci = entry({"rpc", "uci"}, call("rpc_uci"))
|
||||
uci.sysauth = "root"
|
||||
uci.sysauth_authenticator = authenticator
|
||||
uci.notemplate = true
|
||||
|
||||
fs = entry({"rpc", "fs"}, call("rpc_fs"))
|
||||
fs.sysauth = "root"
|
||||
fs.sysauth_authenticator = authenticator
|
||||
fs.notemplate = true
|
||||
|
||||
sys = entry({"rpc", "sys"}, call("rpc_sys"))
|
||||
sys.sysauth = "root"
|
||||
sys.sysauth_authenticator = authenticator
|
||||
sys.notemplate = true
|
||||
|
||||
ipkg = entry({"rpc", "ipkg"}, call("rpc_ipkg"))
|
||||
ipkg.sysauth = "root"
|
||||
ipkg.sysauth_authenticator = authenticator
|
||||
ipkg.notemplate = true
|
||||
|
||||
uci = entry({"rpc", "auth"}, call("rpc_auth"))
|
||||
entry({"rpc", "auth"}, call("rpc_auth")).notemplate = true
|
||||
end
|
||||
|
||||
function rpc_auth()
|
||||
|
|
Loading…
Reference in a new issue