* Rewrote Luci to be coroutine-safe allowing the use of non-forking webservers
* Setting base version to 0.7
This commit is contained in:
parent
50fd298415
commit
855b7582d3
27 changed files with 416 additions and 276 deletions
2
Makefile
2
Makefile
|
@ -32,7 +32,7 @@ hostcopy:
|
||||||
mkdir -p host
|
mkdir -p host
|
||||||
for i in $(MODULES); do cp -a $$i/dist/* host/ -R 2>/dev/null || true; done
|
for i in $(MODULES); do cp -a $$i/dist/* host/ -R 2>/dev/null || true; done
|
||||||
rm -f host/luci
|
rm -f host/luci
|
||||||
ln -s .$(LUCI_INSTALLDIR) host/luci
|
ln -s .$(LUCI_MODULEDIR) host/luci
|
||||||
|
|
||||||
run: host
|
run: host
|
||||||
libs/sgi-webuci/host/buildconfig.sh `pwd`/host > host/etc/boa/boa.conf
|
libs/sgi-webuci/host/buildconfig.sh `pwd`/host > host/etc/boa/boa.conf
|
||||||
|
|
6
NOTICE
6
NOTICE
|
@ -1,7 +1,13 @@
|
||||||
LuCI - Lua Configuration Interface
|
LuCI - Lua Configuration Interface
|
||||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||||
|
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
|
||||||
Licensed under the Apache License, Version 2.0.
|
Licensed under the Apache License, Version 2.0.
|
||||||
|
|
||||||
|
Contains code from:
|
||||||
|
BinDecHex - Copyright 2007 Tim Kelly/Dialectronics
|
||||||
|
coxpcall - Copyright 2005 - Kepler Project (www.keplerproject.org)
|
||||||
|
|
||||||
|
|
||||||
Luci-Statistics - Statistics for LuCI
|
Luci-Statistics - Statistics for LuCI
|
||||||
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
|
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
|
||||||
Licensed under the Apache License, Version 2.0.
|
Licensed under the Apache License, Version 2.0.
|
||||||
|
|
|
@ -12,7 +12,7 @@ function index()
|
||||||
end
|
end
|
||||||
|
|
||||||
function action_activate()
|
function action_activate()
|
||||||
local mac = luci.sys.net.ip4mac(luci.http.env.REMOTE_ADDR)
|
local mac = luci.sys.net.ip4mac(luci.http.getenv("REMOTE_ADDR"))
|
||||||
if mac and luci.http.formvalue("accept") then
|
if mac and luci.http.formvalue("accept") then
|
||||||
os.execute("luci-splash add "..mac.." >/dev/null 2>&1")
|
os.execute("luci-splash add "..mac.." >/dev/null 2>&1")
|
||||||
luci.http.redirect(luci.model.uci.get("freifunk", "community", "homepage"))
|
luci.http.redirect(luci.model.uci.get("freifunk", "community", "homepage"))
|
||||||
|
|
|
@ -149,8 +149,8 @@ function statistics_render()
|
||||||
require("luci.model.uci")
|
require("luci.model.uci")
|
||||||
|
|
||||||
local vars = luci.http.formvalues()
|
local vars = luci.http.formvalues()
|
||||||
local req = luci.dispatcher.request
|
local req = luci.dispatcher.context.request
|
||||||
local path = luci.dispatcher.dispatched.path
|
local path = luci.dispatcher.context.dispatched.path
|
||||||
local uci = luci.model.uci
|
local uci = luci.model.uci
|
||||||
local spans = luci.util.split( uci.get( "luci_statistics", "collectd_rrdtool", "RRATimespans" ), "%s+", nil, true )
|
local spans = luci.util.split( uci.get( "luci_statistics", "collectd_rrdtool", "RRATimespans" ), "%s+", nil, true )
|
||||||
local span = vars.timespan or uci.get( "luci_statistics", "rrdtool", "default_timespan" ) or spans[1]
|
local span = vars.timespan or uci.get( "luci_statistics", "rrdtool", "default_timespan" ) or spans[1]
|
||||||
|
@ -160,10 +160,10 @@ function statistics_render()
|
||||||
local images = { }
|
local images = { }
|
||||||
|
|
||||||
-- find requested plugin and instance
|
-- find requested plugin and instance
|
||||||
for i, p in ipairs( luci.dispatcher.dispatched.path ) do
|
for i, p in ipairs( luci.dispatcher.context.dispatched.path ) do
|
||||||
if luci.dispatcher.dispatched.path[i] == "graph" then
|
if luci.dispatcher.context.dispatched.path[i] == "graph" then
|
||||||
plugin = luci.dispatcher.dispatched.path[i+1]
|
plugin = luci.dispatcher.context.dispatched.path[i+1]
|
||||||
instances = { luci.dispatcher.dispatched.path[i+2] }
|
instances = { luci.dispatcher.context.dispatched.path[i+2] }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -500,7 +500,7 @@ function Graph.render( self, plugin, plugin_instance )
|
||||||
|
|
||||||
-- check for a whole graph handler
|
-- check for a whole graph handler
|
||||||
local plugin_def = "luci.statistics.rrdtool.definitions." .. plugin
|
local plugin_def = "luci.statistics.rrdtool.definitions." .. plugin
|
||||||
local stat, def = pcall( require, plugin_def )
|
local stat, def = luci.util.copcall( require, plugin_def )
|
||||||
|
|
||||||
if stat and def and type(def.rrdargs) == "function" then
|
if stat and def and type(def.rrdargs) == "function" then
|
||||||
|
|
||||||
|
@ -539,7 +539,7 @@ function Graph.render( self, plugin, plugin_instance )
|
||||||
|
|
||||||
-- check for data type handler
|
-- check for data type handler
|
||||||
local dtype_def = plugin_def .. "." .. dtype
|
local dtype_def = plugin_def .. "." .. dtype
|
||||||
local stat, def = pcall( require, dtype_def )
|
local stat, def = luci.util.copcall( require, dtype_def )
|
||||||
|
|
||||||
if stat and def and type(def.rrdargs) == "function" then
|
if stat and def and type(def.rrdargs) == "function" then
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
LUAC = luac
|
LUAC = luac
|
||||||
LUAC_OPTIONS = -s
|
LUAC_OPTIONS = -s
|
||||||
LUCI_INSTALLDIR = /usr/lib/lua/luci
|
|
||||||
|
LUA_MODULEDIR = /usr/lib/lua
|
||||||
|
LUA_LIBRARYDIR = /usr/lib/lua
|
||||||
|
|
||||||
|
LUCI_MODULEDIR = $(LUA_MODULEDIR)/luci
|
||||||
|
LUCI_LIBRARYDIR = $(LUA_LIBRARYDIR)/luci
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,11 @@ compile:
|
||||||
clean: luaclean
|
clean: luaclean
|
||||||
|
|
||||||
luasource:
|
luasource:
|
||||||
mkdir -p dist$(LUCI_INSTALLDIR)
|
mkdir -p dist$(LUA_MODULEDIR)
|
||||||
|
mkdir -p dist$(LUCI_MODULEDIR)
|
||||||
cp -a root/* dist -R 2>/dev/null || true
|
cp -a root/* dist -R 2>/dev/null || true
|
||||||
cp -a luasrc/* dist$(LUCI_INSTALLDIR) -R 2>/dev/null || true
|
cp -a luasrc/* dist$(LUCI_MODULEDIR) -R 2>/dev/null || true
|
||||||
|
cp -a lua/* dist$(LUA_MODULEDIR) -R 2>/dev/null || true
|
||||||
for i in $$(find dist -name .svn); do rm $$i -rf; done
|
for i in $$(find dist -name .svn); do rm $$i -rf; done
|
||||||
|
|
||||||
luacompile: luasource
|
luacompile: luasource
|
||||||
|
|
|
@ -34,8 +34,8 @@ $(LUAPOSIX_DIR)/.patched: $(LUAPOSIX_DIR)/.prepared $(LUAPOSIX_PATCHDIR)/series
|
||||||
|
|
||||||
compile: $(LUAPOSIX_DIR)/.patched
|
compile: $(LUAPOSIX_DIR)/.patched
|
||||||
$(MAKE) -C $(LUAPOSIX_DIR) CC=$(CC) CFLAGS="$(CFLAGS) $(LUA_CFLAGS)" LDFLAGS="$(LDFLAGS) $(LUA_SHLIBS)" OS="$(OS)"
|
$(MAKE) -C $(LUAPOSIX_DIR) CC=$(CC) CFLAGS="$(CFLAGS) $(LUA_CFLAGS)" LDFLAGS="$(LDFLAGS) $(LUA_SHLIBS)" OS="$(OS)"
|
||||||
mkdir -p dist/usr/lib/lua
|
mkdir -p dist$(LUA_LIBRARYDIR)
|
||||||
cp $(LUAPOSIX_DIR)/posix.so dist/usr/lib/lua/
|
cp $(LUAPOSIX_DIR)/posix.so dist$(LUA_LIBRARYDIR)
|
||||||
|
|
||||||
luasource:
|
luasource:
|
||||||
compile-all: compile
|
compile-all: compile
|
||||||
|
|
|
@ -5,7 +5,7 @@ PKG_SOURCE_URL:=https://dev.leipzig.freifunk.net/svn/ff-luci/$(PKG_BRANCH)
|
||||||
PKG_REV:=$(shell LC_ALL=C svn info ${PKG_SOURCE_URL} | sed -ne's/^Last Changed Rev: //p')
|
PKG_REV:=$(shell LC_ALL=C svn info ${PKG_SOURCE_URL} | sed -ne's/^Last Changed Rev: //p')
|
||||||
|
|
||||||
PKG_NAME:=luci
|
PKG_NAME:=luci
|
||||||
PKG_VERSION:=0.6+svn$(PKG_REV)
|
PKG_VERSION:=0.7+svn$(PKG_REV)
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<%+header%>
|
<%+header%>
|
||||||
<form method="post" action="<%=luci.http.env.REQUEST_URI%>">
|
<form method="post" action="<%=luci.http.getenv("REQUEST_URI")%>">
|
||||||
<div>
|
<div>
|
||||||
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
|
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
|
||||||
<input type="hidden" name="cbi.submit" value="1" />
|
<input type="hidden" name="cbi.submit" value="1" />
|
||||||
|
|
|
@ -25,5 +25,5 @@ limitations under the License.
|
||||||
]]--
|
]]--
|
||||||
module("luci", package.seeall)
|
module("luci", package.seeall)
|
||||||
|
|
||||||
__version__ = "0.6"
|
__version__ = "0.7"
|
||||||
__appname__ = "LuCI"
|
__appname__ = "LuCI"
|
||||||
|
|
|
@ -36,7 +36,7 @@ function class(base)
|
||||||
setmetatable(inst, {__index = class})
|
setmetatable(inst, {__index = class})
|
||||||
|
|
||||||
if inst.__init__ then
|
if inst.__init__ then
|
||||||
local stat, err = pcall(inst.__init__, inst, ...)
|
local stat, err = copcall(inst.__init__, inst, ...)
|
||||||
if not stat then
|
if not stat then
|
||||||
error(err)
|
error(err)
|
||||||
end
|
end
|
||||||
|
@ -152,6 +152,12 @@ function pcdata(value)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Returns an error message to stdout
|
||||||
|
function perror(obj)
|
||||||
|
io.stderr:write(tostring(obj) .. "\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Resets the scope of f doing a shallow copy of its scope into a new table
|
-- Resets the scope of f doing a shallow copy of its scope into a new table
|
||||||
function resfenv(f)
|
function resfenv(f)
|
||||||
setfenv(f, clone(getfenv(f)))
|
setfenv(f, clone(getfenv(f)))
|
||||||
|
@ -255,6 +261,34 @@ function strip_bytecode(dump)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Creates a new threadlocal store
|
||||||
|
function threadlocal()
|
||||||
|
local tbl = {}
|
||||||
|
|
||||||
|
local function get(self, key)
|
||||||
|
local c = coroutine.running()
|
||||||
|
local thread = coxpt[c] or c or 0
|
||||||
|
if not rawget(self, thread) then
|
||||||
|
rawset(self, thread, {})
|
||||||
|
end
|
||||||
|
return rawget(self, thread)[key]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function set(self, key, value)
|
||||||
|
local c = coroutine.running()
|
||||||
|
local thread = coxpt[c] or c or 0
|
||||||
|
if not rawget(self, thread) then
|
||||||
|
rawset(self, thread, {})
|
||||||
|
end
|
||||||
|
rawget(self, thread)[key] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
setmetatable(tbl, {__index = get, __newindex = set})
|
||||||
|
|
||||||
|
return tbl
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Removes whitespace from beginning and end of a string
|
-- Removes whitespace from beginning and end of a string
|
||||||
function trim(str)
|
function trim(str)
|
||||||
local s = str:gsub("^%s*(.-)%s*$", "%1")
|
local s = str:gsub("^%s*(.-)%s*$", "%1")
|
||||||
|
@ -355,3 +389,46 @@ end
|
||||||
function vspairs(t)
|
function vspairs(t)
|
||||||
return _sortiter( t, function (a,b) return t[a] < t[b] end )
|
return _sortiter( t, function (a,b) return t[a] < t[b] end )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Coroutine safe xpcall and pcall versions modified for Luci
|
||||||
|
-- original version:
|
||||||
|
-- coxpcall 1.13 - Copyright 2005 - Kepler Project (www.keplerproject.org)
|
||||||
|
local performResume, handleReturnValue
|
||||||
|
local oldpcall, oldxpcall = pcall, xpcall
|
||||||
|
coxpt = {}
|
||||||
|
|
||||||
|
function handleReturnValue(err, co, status, ...)
|
||||||
|
if not status then
|
||||||
|
return false, err(debug.traceback(co, (...)), ...)
|
||||||
|
end
|
||||||
|
if coroutine.status(co) == 'suspended' then
|
||||||
|
return performResume(err, co, coroutine.yield(...))
|
||||||
|
else
|
||||||
|
return true, ...
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function performResume(err, co, ...)
|
||||||
|
return handleReturnValue(err, co, coroutine.resume(co, ...))
|
||||||
|
end
|
||||||
|
|
||||||
|
function coxpcall(f, err, ...)
|
||||||
|
local res, co = oldpcall(coroutine.create, f)
|
||||||
|
if not res then
|
||||||
|
local params = {...}
|
||||||
|
local newf = function() return f(unpack(params)) end
|
||||||
|
co = coroutine.create(newf)
|
||||||
|
end
|
||||||
|
local c = coroutine.running()
|
||||||
|
coxpt[co] = coxpt[c] or c or 0
|
||||||
|
return performResume(err, co, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function id(trace, ...)
|
||||||
|
return ...
|
||||||
|
end
|
||||||
|
|
||||||
|
function copcall(f, ...)
|
||||||
|
return coxpcall(f, id, ...)
|
||||||
|
end
|
||||||
|
|
|
@ -6,8 +6,8 @@ include ../../build/gccconfig.mk
|
||||||
$(COMPILE) $(LUA_CFLAGS) $(FPIC) -c -o $@ $<
|
$(COMPILE) $(LUA_CFLAGS) $(FPIC) -c -o $@ $<
|
||||||
|
|
||||||
compile: src/fastindex.o
|
compile: src/fastindex.o
|
||||||
mkdir -p dist$(LUCI_INSTALLDIR)
|
mkdir -p dist$(LUCI_LIBRARYDIR)
|
||||||
$(LINK) $(SHLIB_FLAGS) -o dist$(LUCI_INSTALLDIR)/fastindex.so src/fastindex.o $(LUA_SHLIBS)
|
$(LINK) $(SHLIB_FLAGS) -o dist$(LUCI_LIBRARYDIR)/fastindex.so src/fastindex.o $(LUA_SHLIBS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f src/*.o
|
rm -f src/*.o
|
||||||
|
|
|
@ -24,80 +24,49 @@ limitations under the License.
|
||||||
|
|
||||||
]]--
|
]]--
|
||||||
module("luci.sgi.haserl", package.seeall)
|
module("luci.sgi.haserl", package.seeall)
|
||||||
require("luci.fs")
|
require("luci.http")
|
||||||
|
require("luci.util")
|
||||||
|
require("luci.dispatcher")
|
||||||
|
|
||||||
-- Environment Table
|
function run()
|
||||||
luci.http.env = ENV
|
local r = luci.http.Request()
|
||||||
|
r.env = ENV
|
||||||
|
r.request = normalize_table(FORM)
|
||||||
|
|
||||||
-- Enforces user authentification
|
local x = coroutine.create(luci.dispatcher.httpdispatch)
|
||||||
function luci.http.basic_auth(verify_callback, realm)
|
while coroutine.status(x) ~= "dead" do
|
||||||
-- Dummy for Haserl
|
local res, id, data1, data2 = coroutine.resume(x, r)
|
||||||
return true
|
|
||||||
|
if not res then
|
||||||
|
print("Status: 500 Internal Server Error")
|
||||||
|
print("Content-Type: text/plain\n")
|
||||||
|
print(id)
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
|
||||||
|
if id == 1 then
|
||||||
|
io.write("Status: " .. tostring(data1) .. " " .. data2 .. "\n")
|
||||||
|
elseif id == 2 then
|
||||||
|
io.write(data1 .. ": " .. data2 .. "\n")
|
||||||
|
elseif id == 3 then
|
||||||
|
io.write("\n")
|
||||||
|
elseif id == 4 then
|
||||||
|
io.write(data1)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns the main dispatcher URL
|
function normalize_table(table, prefix)
|
||||||
function luci.http.dispatcher()
|
prefix = prefix and prefix .. "." or ""
|
||||||
return luci.http.env.SCRIPT_NAME or ""
|
local new = {}
|
||||||
end
|
|
||||||
|
|
||||||
-- Returns the upload dispatcher URL
|
for k,v in pairs(table) do
|
||||||
function luci.http.dispatcher_upload()
|
if type(v) == "table" and #v == 0 then
|
||||||
return luci.http.dispatcher() .. "-upload"
|
luci.util.update(new, normalize_table(v, prefix .. k))
|
||||||
end
|
else
|
||||||
|
new[prefix .. k] = v
|
||||||
-- Returns a table of all COOKIE, GET and POST Parameters
|
|
||||||
function luci.http.formvalues()
|
|
||||||
return FORM
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Gets form value from key
|
|
||||||
function luci.http.formvalue(key, default)
|
|
||||||
local c = luci.http.formvalues()
|
|
||||||
|
|
||||||
for match in key:gmatch("[%w-_]+") do
|
|
||||||
c = c[match]
|
|
||||||
if c == nil then
|
|
||||||
return default
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return c
|
return new
|
||||||
end
|
|
||||||
|
|
||||||
-- Gets a table of values with a certain prefix
|
|
||||||
function luci.http.formvaluetable(prefix)
|
|
||||||
return luci.http.formvalue(prefix, {})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Sends a custom HTTP-Header
|
|
||||||
function luci.http.header(key, value)
|
|
||||||
print(key .. ": " .. value)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Set Content-Type
|
|
||||||
function luci.http.prepare_content(type)
|
|
||||||
print("Content-Type: "..type.."\n")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Asks the browser to redirect to "url"
|
|
||||||
function luci.http.redirect(url)
|
|
||||||
luci.http.status(302, "Found")
|
|
||||||
luci.http.header("Location", url)
|
|
||||||
print()
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Returns the path of an uploaded file
|
|
||||||
-- WARNING! File uploads can be easily spoofed! Do additional sanity checks!
|
|
||||||
function luci.http.upload(name)
|
|
||||||
local fpath = luci.http.formvalue(name)
|
|
||||||
local fname = luci.http.formvalue(name .. "_name")
|
|
||||||
|
|
||||||
if fpath and fname and luci.fs.isfile(fpath) then
|
|
||||||
return fpath
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Sets HTTP-Status-Header
|
|
||||||
function luci.http.status(code, message)
|
|
||||||
print("Status: " .. tostring(code) .. " " .. message)
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/haserl --shell=luac
|
#!/usr/bin/haserl --shell=luac
|
||||||
require("luci.dispatcher")
|
require("luci.sgi.haserl")
|
||||||
luci.dispatcher.indexcache = "/tmp/.luciindex"
|
luci.dispatcher.indexcache = "/tmp/.luciindex"
|
||||||
luci.dispatcher.httpdispatch()
|
luci.sgi.haserl.run()
|
|
@ -24,93 +24,36 @@ limitations under the License.
|
||||||
|
|
||||||
]]--
|
]]--
|
||||||
module("luci.sgi.webuci", package.seeall)
|
module("luci.sgi.webuci", package.seeall)
|
||||||
|
require("luci.http")
|
||||||
|
require("luci.util")
|
||||||
|
require("luci.dispatcher")
|
||||||
|
|
||||||
local status_set = false
|
function run(env, vars)
|
||||||
|
local r = luci.http.Request()
|
||||||
|
r.env = env
|
||||||
|
r.request = vars
|
||||||
|
|
||||||
-- Initialize the environment
|
local x = coroutine.create(luci.dispatcher.httpdispatch)
|
||||||
function initenv(env, vars)
|
|
||||||
luci.http.env = env
|
|
||||||
luci.http.vars = vars
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Enforces user authentification
|
while coroutine.status(x) ~= "dead" do
|
||||||
function luci.http.basic_auth(verify_callback, realm)
|
local res, id, data1, data2 = coroutine.resume(x, r)
|
||||||
local user = luci.http.env.auth_user
|
|
||||||
local pass = luci.http.env.auth_password
|
|
||||||
realm = realm or ""
|
|
||||||
|
|
||||||
if not user or not verify_callback(user, pass) then
|
if not res then
|
||||||
luci.http.status("401", "Unauthorized")
|
print(env.SERVER_PROTOCOL .. " 500 Internal Server Error")
|
||||||
luci.http.header("WWW-Authenticate", string.format('Basic realm="%s"', realm))
|
print("Content-Type: text/plain\n")
|
||||||
return false
|
print(id)
|
||||||
else
|
break;
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Returns the main dispatcher URL
|
|
||||||
function luci.http.dispatcher()
|
|
||||||
return luci.http.env.SCRIPT_NAME or ""
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Returns the upload dispatcher URL
|
|
||||||
function luci.http.dispatcher_upload()
|
|
||||||
-- To be implemented
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Returns a table of all COOKIE, GET and POST Parameters
|
|
||||||
function luci.http.formvalues()
|
|
||||||
return luci.http.vars
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Gets form value from key
|
|
||||||
function luci.http.formvalue(key, default)
|
|
||||||
return luci.http.formvalues()[key] or default
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Gets a table of values with a certain prefix
|
|
||||||
function luci.http.formvaluetable(prefix)
|
|
||||||
local vals = {}
|
|
||||||
prefix = prefix and prefix .. "." or "."
|
|
||||||
|
|
||||||
for k, v in pairs(luci.http.formvalues()) do
|
|
||||||
if k:find(prefix, 1, true) == 1 then
|
|
||||||
vals[k:sub(#prefix + 1)] = v
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return vals
|
if id == 1 then
|
||||||
end
|
io.write(env.SERVER_PROTOCOL .. " " .. tostring(data1) .. " " .. data2 .. "\n")
|
||||||
|
elseif id == 2 then
|
||||||
-- Sends a custom HTTP-Header
|
io.write(data1 .. ": " .. data2 .. "\n")
|
||||||
function luci.http.header(key, value)
|
elseif id == 3 then
|
||||||
print(key .. ": " .. value)
|
io.write("\n")
|
||||||
end
|
elseif id == 4 then
|
||||||
|
io.write(data1)
|
||||||
-- Set Content-Type
|
|
||||||
function luci.http.prepare_content(type)
|
|
||||||
if not status_set then
|
|
||||||
luci.http.status(200, "OK")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
print("Content-Type: "..type.."\n")
|
end
|
||||||
end
|
|
||||||
|
|
||||||
-- Asks the browser to redirect to "url"
|
|
||||||
function luci.http.redirect(url)
|
|
||||||
luci.http.status(302, "Found")
|
|
||||||
luci.http.header("Location", url)
|
|
||||||
print()
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Returns the path of an uploaded file
|
|
||||||
-- WARNING! File uploads can be easily spoofed! Do additional sanity checks!
|
|
||||||
function luci.http.upload(name)
|
|
||||||
-- To be implemented
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Sets HTTP-Status-Header
|
|
||||||
function luci.http.status(code, message)
|
|
||||||
print(luci.http.env.SERVER_PROTOCOL .. " " .. tostring(code) .. " " .. message)
|
|
||||||
status_set = true
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -60,6 +60,5 @@ function handle_req(context)
|
||||||
env.SERVER_ADDR = context.server_addr
|
env.SERVER_ADDR = context.server_addr
|
||||||
env.SCRIPT_NAME = env.REQUEST_URI:sub(1, #env.REQUEST_URI - #env.PATH_INFO)
|
env.SCRIPT_NAME = env.REQUEST_URI:sub(1, #env.REQUEST_URI - #env.PATH_INFO)
|
||||||
|
|
||||||
luci.sgi.webuci.initenv(env, vars)
|
luci.sgi.webuci.run(env, vars)
|
||||||
luci.dispatcher.httpdispatch()
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -27,7 +27,7 @@ local uci = require("uci")
|
||||||
local util = require("luci.util")
|
local util = require("luci.util")
|
||||||
local setmetatable, rawget, rawset = setmetatable, rawget, rawset
|
local setmetatable, rawget, rawset = setmetatable, rawget, rawset
|
||||||
local error, pairs, ipairs, tostring = error, pairs, ipairs, tostring
|
local error, pairs, ipairs, tostring = error, pairs, ipairs, tostring
|
||||||
local table, print = table, print
|
local table = table
|
||||||
|
|
||||||
module("luci.model.uci", function(m) setmetatable(m, {__index = uci}) end)
|
module("luci.model.uci", function(m) setmetatable(m, {__index = uci}) end)
|
||||||
|
|
||||||
|
|
|
@ -34,21 +34,10 @@ if (os.time() < 1000000000) then
|
||||||
os.execute('date -s '..os.date('%m%d%H%M%Y', luci.fs.mtime(luci.sys.libpath() .. "/dispatcher.lua"))..' > /dev/null 2>&1')
|
os.execute('date -s '..os.date('%m%d%H%M%Y', luci.fs.mtime(luci.sys.libpath() .. "/dispatcher.lua"))..' > /dev/null 2>&1')
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Local dispatch database
|
context = luci.util.threadlocal()
|
||||||
local tree = {nodes={}}
|
|
||||||
|
|
||||||
-- Index table
|
-- Index table
|
||||||
local index = {}
|
local index = nil
|
||||||
|
|
||||||
-- Global request object
|
|
||||||
request = {}
|
|
||||||
|
|
||||||
-- Active dispatched node
|
|
||||||
dispatched = nil
|
|
||||||
|
|
||||||
-- Status fields
|
|
||||||
built_index = false
|
|
||||||
built_tree = false
|
|
||||||
|
|
||||||
-- Fastindex
|
-- Fastindex
|
||||||
local fi
|
local fi
|
||||||
|
@ -64,9 +53,9 @@ function error401(message)
|
||||||
message = message or "Unauthorized"
|
message = message or "Unauthorized"
|
||||||
|
|
||||||
require("luci.template")
|
require("luci.template")
|
||||||
if not pcall(luci.template.render, "error401") then
|
if not luci.util.copcall(luci.template.render, "error401") then
|
||||||
luci.http.prepare_content("text/plain")
|
luci.http.prepare_content("text/plain")
|
||||||
print(message)
|
luci.http.write(message)
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
@ -77,9 +66,9 @@ function error404(message)
|
||||||
message = message or "Not Found"
|
message = message or "Not Found"
|
||||||
|
|
||||||
require("luci.template")
|
require("luci.template")
|
||||||
if not pcall(luci.template.render, "error404") then
|
if not luci.util.copcall(luci.template.render, "error404") then
|
||||||
luci.http.prepare_content("text/plain")
|
luci.http.prepare_content("text/plain")
|
||||||
print(message)
|
luci.http.write(message)
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
@ -89,31 +78,39 @@ function error500(message)
|
||||||
luci.http.status(500, "Internal Server Error")
|
luci.http.status(500, "Internal Server Error")
|
||||||
|
|
||||||
require("luci.template")
|
require("luci.template")
|
||||||
if not pcall(luci.template.render, "error500", {message=message}) then
|
if not luci.util.copcall(luci.template.render, "error500", {message=message}) then
|
||||||
luci.http.prepare_content("text/plain")
|
luci.http.prepare_content("text/plain")
|
||||||
print(message)
|
luci.http.write(message)
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Creates a request object for dispatching
|
-- Creates a request object for dispatching
|
||||||
function httpdispatch()
|
function httpdispatch(request)
|
||||||
local pathinfo = luci.http.env.PATH_INFO or ""
|
luci.http.context.request = request
|
||||||
|
context.request = {}
|
||||||
|
local pathinfo = request.env.PATH_INFO or ""
|
||||||
|
|
||||||
for node in pathinfo:gmatch("[^/]+") do
|
for node in pathinfo:gmatch("[^/]+") do
|
||||||
table.insert(request, node)
|
table.insert(context.request, node)
|
||||||
end
|
end
|
||||||
|
|
||||||
dispatch()
|
dispatch(context.request)
|
||||||
|
luci.http.close()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Dispatches a request
|
-- Dispatches a request
|
||||||
function dispatch()
|
function dispatch(request)
|
||||||
if not built_tree then
|
context.path = request
|
||||||
|
|
||||||
|
require("luci.i18n")
|
||||||
|
luci.i18n.setlanguage(require("luci.config").main.lang)
|
||||||
|
|
||||||
|
if not context.tree then
|
||||||
createtree()
|
createtree()
|
||||||
end
|
end
|
||||||
|
|
||||||
local c = tree
|
local c = context.tree
|
||||||
local track = {}
|
local track = {}
|
||||||
|
|
||||||
for i, s in ipairs(request) do
|
for i, s in ipairs(request) do
|
||||||
|
@ -131,6 +128,7 @@ function dispatch()
|
||||||
local accs = track.sysauth
|
local accs = track.sysauth
|
||||||
accs = (type(accs) == "string") and {accs} or accs
|
accs = (type(accs) == "string") and {accs} or accs
|
||||||
|
|
||||||
|
--[[
|
||||||
local function sysauth(user, password)
|
local function sysauth(user, password)
|
||||||
return (luci.util.contains(accs, user)
|
return (luci.util.contains(accs, user)
|
||||||
and luci.sys.user.checkpasswd(user, password))
|
and luci.sys.user.checkpasswd(user, password))
|
||||||
|
@ -140,6 +138,7 @@ function dispatch()
|
||||||
error401()
|
error401()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
]]--
|
||||||
end
|
end
|
||||||
|
|
||||||
if track.i18n then
|
if track.i18n then
|
||||||
|
@ -156,22 +155,24 @@ function dispatch()
|
||||||
|
|
||||||
-- Init template engine
|
-- Init template engine
|
||||||
local tpl = require("luci.template")
|
local tpl = require("luci.template")
|
||||||
tpl.viewns.translate = function(...) return require("luci.i18n").translate(...) end
|
local viewns = {}
|
||||||
tpl.viewns.controller = luci.http.dispatcher()
|
tpl.context.viewns = viewns
|
||||||
tpl.viewns.uploadctrl = luci.http.dispatcher_upload() -- DEPRECATED
|
viewns.write = luci.http.write
|
||||||
tpl.viewns.media = luci.config.main.mediaurlbase
|
viewns.translate = function(...) return require("luci.i18n").translate(...) end
|
||||||
tpl.viewns.resource = luci.config.main.resourcebase
|
viewns.controller = luci.http.getenv("SCRIPT_NAME")
|
||||||
tpl.viewns.REQUEST_URI = luci.http.env.SCRIPT_NAME .. (luci.http.env.PATH_INFO or "")
|
viewns.media = luci.config.main.mediaurlbase
|
||||||
|
viewns.resource = luci.config.main.resourcebase
|
||||||
|
viewns.REQUEST_URI = luci.http.getenv("SCRIPT_NAME") .. (luci.http.getenv("PATH_INFO") or "")
|
||||||
|
|
||||||
|
|
||||||
if c and type(c.target) == "function" then
|
if c and type(c.target) == "function" then
|
||||||
dispatched = c
|
context.dispatched = c
|
||||||
stat, mod = pcall(require, c.module)
|
stat, mod = luci.util.copcall(require, c.module)
|
||||||
if stat then
|
if stat then
|
||||||
luci.util.updfenv(c.target, mod)
|
luci.util.updfenv(c.target, mod)
|
||||||
end
|
end
|
||||||
|
|
||||||
stat, err = pcall(c.target)
|
stat, err = luci.util.copcall(c.target)
|
||||||
if not stat then
|
if not stat then
|
||||||
error500(err)
|
error500(err)
|
||||||
end
|
end
|
||||||
|
@ -182,21 +183,20 @@ end
|
||||||
|
|
||||||
-- Generates the dispatching tree
|
-- Generates the dispatching tree
|
||||||
function createindex()
|
function createindex()
|
||||||
index = {}
|
|
||||||
local path = luci.sys.libpath() .. "/controller/"
|
local path = luci.sys.libpath() .. "/controller/"
|
||||||
local suff = ".lua"
|
local suff = ".lua"
|
||||||
|
|
||||||
if pcall(require, "luci.fastindex") then
|
if luci.util.copcall(require, "luci.fastindex") then
|
||||||
createindex_fastindex(path, suff)
|
createindex_fastindex(path, suff)
|
||||||
else
|
else
|
||||||
createindex_plain(path, suff)
|
createindex_plain(path, suff)
|
||||||
end
|
end
|
||||||
|
|
||||||
built_index = true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Uses fastindex to create the dispatching tree
|
-- Uses fastindex to create the dispatching tree
|
||||||
function createindex_fastindex(path, suffix)
|
function createindex_fastindex(path, suffix)
|
||||||
|
index = {}
|
||||||
|
|
||||||
if not fi then
|
if not fi then
|
||||||
fi = luci.fastindex.new("index")
|
fi = luci.fastindex.new("index")
|
||||||
fi.add(path .. "*" .. suffix)
|
fi.add(path .. "*" .. suffix)
|
||||||
|
@ -212,9 +212,7 @@ end
|
||||||
-- Calls the index function of all available controllers
|
-- Calls the index function of all available controllers
|
||||||
-- Fallback for transition purposes / Leave it in as long as it works otherwise throw it away
|
-- Fallback for transition purposes / Leave it in as long as it works otherwise throw it away
|
||||||
function createindex_plain(path, suffix)
|
function createindex_plain(path, suffix)
|
||||||
if built_index then
|
index = {}
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local cache = nil
|
local cache = nil
|
||||||
|
|
||||||
|
@ -246,7 +244,7 @@ function createindex_plain(path, suffix)
|
||||||
end
|
end
|
||||||
|
|
||||||
if not cache or stime > ctime then
|
if not cache or stime > ctime then
|
||||||
stat, mod = pcall(require, module)
|
stat, mod = luci.util.copcall(require, module)
|
||||||
|
|
||||||
if stat and mod and type(mod.index) == "function" then
|
if stat and mod and type(mod.index) == "function" then
|
||||||
index[module] = mod.index
|
index[module] = mod.index
|
||||||
|
@ -263,10 +261,11 @@ end
|
||||||
|
|
||||||
-- Creates the dispatching tree from the index
|
-- Creates the dispatching tree from the index
|
||||||
function createtree()
|
function createtree()
|
||||||
if not built_index then
|
if not index then
|
||||||
createindex()
|
createindex()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context.tree = {nodes={}}
|
||||||
require("luci.i18n")
|
require("luci.i18n")
|
||||||
|
|
||||||
-- Load default translation
|
-- Load default translation
|
||||||
|
@ -283,14 +282,12 @@ function createtree()
|
||||||
scope._NAME = k
|
scope._NAME = k
|
||||||
setfenv(v, scope)
|
setfenv(v, scope)
|
||||||
|
|
||||||
local stat, err = pcall(v)
|
local stat, err = luci.util.copcall(v)
|
||||||
if not stat then
|
if not stat then
|
||||||
error500(err)
|
error500(err)
|
||||||
os.exit(1)
|
os.exit(1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
built_tree = true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Reassigns a node to another position
|
-- Reassigns a node to another position
|
||||||
|
@ -302,7 +299,7 @@ function assign(path, clone, title, order)
|
||||||
obj.title = title
|
obj.title = title
|
||||||
obj.order = order
|
obj.order = order
|
||||||
|
|
||||||
local c = tree
|
local c = context.tree
|
||||||
for k, v in ipairs(clone) do
|
for k, v in ipairs(clone) do
|
||||||
if not c.nodes[v] then
|
if not c.nodes[v] then
|
||||||
c.nodes[v] = {nodes={}}
|
c.nodes[v] = {nodes={}}
|
||||||
|
@ -330,8 +327,7 @@ end
|
||||||
|
|
||||||
-- Fetch a dispatching node
|
-- Fetch a dispatching node
|
||||||
function node(...)
|
function node(...)
|
||||||
local c = tree
|
local c = context.tree
|
||||||
|
|
||||||
arg.n = nil
|
arg.n = nil
|
||||||
if arg[1] then
|
if arg[1] then
|
||||||
if type(arg[1]) == "table" then
|
if type(arg[1]) == "table" then
|
||||||
|
@ -357,8 +353,7 @@ end
|
||||||
function alias(...)
|
function alias(...)
|
||||||
local req = arg
|
local req = arg
|
||||||
return function()
|
return function()
|
||||||
request = req
|
dispatch(req)
|
||||||
dispatch()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -366,19 +361,20 @@ function rewrite(n, ...)
|
||||||
local req = arg
|
local req = arg
|
||||||
return function()
|
return function()
|
||||||
for i=1,n do
|
for i=1,n do
|
||||||
table.remove(request, 1)
|
table.remove(context.path, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
for i,r in ipairs(req) do
|
for i,r in ipairs(req) do
|
||||||
table.insert(request, i, r)
|
table.insert(context.path, i, r)
|
||||||
end
|
end
|
||||||
|
|
||||||
dispatch()
|
dispatch()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function call(name)
|
function call(name, ...)
|
||||||
return function() getfenv()[name]() end
|
local argv = {...}
|
||||||
|
return function() return getfenv()[name](unpack(argv)) end
|
||||||
end
|
end
|
||||||
|
|
||||||
function template(name)
|
function template(name)
|
||||||
|
@ -391,13 +387,13 @@ function cbi(model)
|
||||||
require("luci.template")
|
require("luci.template")
|
||||||
|
|
||||||
return function()
|
return function()
|
||||||
local stat, res = pcall(luci.cbi.load, model)
|
local stat, res = luci.util.copcall(luci.cbi.load, model)
|
||||||
if not stat then
|
if not stat then
|
||||||
error500(res)
|
error500(res)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
local stat, err = pcall(res.parse, res)
|
local stat, err = luci.util.copcall(res.parse, res)
|
||||||
if not stat then
|
if not stat then
|
||||||
error500(err)
|
error500(err)
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -28,13 +28,141 @@ limitations under the License.
|
||||||
]]--
|
]]--
|
||||||
|
|
||||||
module("luci.http", package.seeall)
|
module("luci.http", package.seeall)
|
||||||
|
require("luci.util")
|
||||||
|
context = luci.util.threadlocal()
|
||||||
|
|
||||||
if ENV and ENV.HASERLVER then
|
|
||||||
require("luci.sgi.haserl")
|
Request = luci.util.class()
|
||||||
elseif webuci then
|
function Request.__init__(self)
|
||||||
require("luci.sgi.webuci")
|
self.headers = {}
|
||||||
|
self.request = {}
|
||||||
|
self.uploads = {}
|
||||||
|
self.env = {}
|
||||||
|
self.data = ""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Request.formvalue(self, name, default)
|
||||||
|
return self.request[name] or default
|
||||||
|
end
|
||||||
|
|
||||||
|
function Request.formvalues(self)
|
||||||
|
return self.request
|
||||||
|
end
|
||||||
|
|
||||||
|
function Request.formvaluetable(self, prefix)
|
||||||
|
local vals = {}
|
||||||
|
prefix = prefix and prefix .. "." or "."
|
||||||
|
|
||||||
|
for k, v in pairs(self.request) do
|
||||||
|
if k:find(prefix, 1, true) == 1 then
|
||||||
|
vals[k:sub(#prefix + 1)] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return vals
|
||||||
|
end
|
||||||
|
|
||||||
|
function Request.getenv(self, name)
|
||||||
|
return self.env[name]
|
||||||
|
end
|
||||||
|
|
||||||
|
function Request.upload(self, name)
|
||||||
|
return self.uploads[name]
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function close()
|
||||||
|
if not context.eoh then
|
||||||
|
context.eoh = true
|
||||||
|
coroutine.yield(3)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not context.closed then
|
||||||
|
context.closed = true
|
||||||
|
coroutine.yield(5)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function formvalue(...)
|
||||||
|
return context.request:formvalue(...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function formvalues(...)
|
||||||
|
return context.request:formvalues(...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function formvaluetable(...)
|
||||||
|
return context.request:formvaluetable(...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function getenv(...)
|
||||||
|
return context.request:getenv(...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function header(key, value)
|
||||||
|
if not context.status then
|
||||||
|
status()
|
||||||
|
end
|
||||||
|
if not context.headers then
|
||||||
|
context.headers = {}
|
||||||
|
end
|
||||||
|
context.headers[key:lower()] = value
|
||||||
|
coroutine.yield(2, key, value)
|
||||||
|
end
|
||||||
|
|
||||||
|
function prepare_content(mime)
|
||||||
|
header("Content-Type", mime)
|
||||||
|
end
|
||||||
|
|
||||||
|
function status(code, message)
|
||||||
|
code = code or 200
|
||||||
|
message = message or "OK"
|
||||||
|
context.status = code
|
||||||
|
coroutine.yield(1, code, message)
|
||||||
|
end
|
||||||
|
|
||||||
|
function write(content)
|
||||||
|
if not content or #content == 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not context.eoh then
|
||||||
|
if not context.status then
|
||||||
|
status()
|
||||||
|
end
|
||||||
|
if not context.headers or not context.headers["content-type"] then
|
||||||
|
header("Content-Type", "text/html; charset=utf-8")
|
||||||
|
end
|
||||||
|
|
||||||
|
context.eoh = true
|
||||||
|
coroutine.yield(3)
|
||||||
|
end
|
||||||
|
coroutine.yield(4, content)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function basic_auth(realm, errorpage)
|
||||||
|
header("Status", "401 Unauthorized")
|
||||||
|
header("WWW-Authenticate", string.format('Basic realm="%s"', realm or ""))
|
||||||
|
|
||||||
|
if errorpage then
|
||||||
|
errorpage()
|
||||||
|
end
|
||||||
|
|
||||||
|
close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function redirect(url)
|
||||||
|
header("Status", "302 Found")
|
||||||
|
header("Location", url)
|
||||||
|
close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function upload(...)
|
||||||
|
return context.request:upload(...)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function build_querystring(table)
|
function build_querystring(table)
|
||||||
local s="?"
|
local s="?"
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,8 @@ require("luci.sys")
|
||||||
table = {}
|
table = {}
|
||||||
i18ndir = luci.sys.libpath() .. "/i18n/"
|
i18ndir = luci.sys.libpath() .. "/i18n/"
|
||||||
loaded = {}
|
loaded = {}
|
||||||
|
context = luci.util.threadlocal()
|
||||||
|
default = "en"
|
||||||
|
|
||||||
-- Clears the translation table
|
-- Clears the translation table
|
||||||
function clear()
|
function clear()
|
||||||
|
@ -37,13 +39,17 @@ function clear()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Loads a translation and copies its data into the global translation table
|
-- Loads a translation and copies its data into the global translation table
|
||||||
function load(file, force)
|
function load(file, lang, force)
|
||||||
if force or not loaded[file] then
|
lang = lang or ""
|
||||||
local f = loadfile(i18ndir..file..".lua") or loadfile(i18ndir..file)
|
if force or not loaded[lang] or not loaded[lang][file] then
|
||||||
|
local f = loadfile(i18ndir .. file .. "." .. lang .. ".lua")
|
||||||
|
or loadfile(i18ndir .. file .. "." .. lang)
|
||||||
if f then
|
if f then
|
||||||
setfenv(f, table)
|
table[lang] = table[lang] or {}
|
||||||
|
setfenv(f, table[lang])
|
||||||
f()
|
f()
|
||||||
loaded[file] = true
|
loaded[lang] = loaded[lang] or {}
|
||||||
|
loaded[lang][file] = true
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
return false
|
return false
|
||||||
|
@ -55,13 +61,20 @@ end
|
||||||
|
|
||||||
-- Same as load but autocompletes the filename with .LANG from config.lang
|
-- Same as load but autocompletes the filename with .LANG from config.lang
|
||||||
function loadc(file, force)
|
function loadc(file, force)
|
||||||
load(file .. ".en", force)
|
load(file, default, force)
|
||||||
return load(file .. "." .. require("luci.config").main.lang, force)
|
return load(file, context.lang, force)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Sets the context language
|
||||||
|
function setlanguage(lang)
|
||||||
|
context.lang = lang
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns the i18n-value defined by "key" or if there is no such: "default"
|
-- Returns the i18n-value defined by "key" or if there is no such: "default"
|
||||||
function translate(key, default)
|
function translate(key, default)
|
||||||
return table[key] or default
|
return (table[context.lang] and table[context.lang][key])
|
||||||
|
or (table[default] and table[default][key])
|
||||||
|
or default
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Translate shourtcut with sprintf/string.format inclusion
|
-- Translate shourtcut with sprintf/string.format inclusion
|
||||||
|
|
|
@ -44,8 +44,9 @@ compiler_mode = luci.config.template.compiler_mode or "memory"
|
||||||
|
|
||||||
|
|
||||||
-- Define the namespace for template modules
|
-- Define the namespace for template modules
|
||||||
|
context = luci.util.threadlocal()
|
||||||
|
|
||||||
viewns = {
|
viewns = {
|
||||||
write = io.write,
|
|
||||||
include = function(name) Template(name):render(getfenv(2)) end,
|
include = function(name) Template(name):render(getfenv(2)) end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +114,7 @@ end
|
||||||
-- Oldstyle render shortcut
|
-- Oldstyle render shortcut
|
||||||
function render(name, scope, ...)
|
function render(name, scope, ...)
|
||||||
scope = scope or getfenv(2)
|
scope = scope or getfenv(2)
|
||||||
local s, t = pcall(Template, name)
|
local s, t = luci.util.copcall(Template, name)
|
||||||
if not s then
|
if not s then
|
||||||
error(t)
|
error(t)
|
||||||
else
|
else
|
||||||
|
@ -141,8 +142,9 @@ function Template.__init__(self, name)
|
||||||
self.viewns = {}
|
self.viewns = {}
|
||||||
|
|
||||||
-- Copy over from general namespace
|
-- Copy over from general namespace
|
||||||
for k, v in pairs(viewns) do
|
luci.util.update(self.viewns, viewns)
|
||||||
self.viewns[k] = v
|
if context.viewns then
|
||||||
|
luci.util.update(self.viewns, context.viewns)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- If we have a cached template, skip compiling and loading
|
-- If we have a cached template, skip compiling and loading
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<p><%:a_s_flash_upgrade1%></p>
|
<p><%:a_s_flash_upgrade1%></p>
|
||||||
<br />
|
<br />
|
||||||
<% if sysupgrade and not ret then %>
|
<% if sysupgrade and not ret then %>
|
||||||
<form method="post" action="<%=uploadctrl%><%=luci.http.env.PATH_INFO%>" enctype="multipart/form-data">
|
<form method="post" action="<%=luci.http.getenv("REQUEST_URI")%>" enctype="multipart/form-data">
|
||||||
<div class="cbi-section-node">
|
<div class="cbi-section-node">
|
||||||
<div class="cbi-value clear">
|
<div class="cbi-value clear">
|
||||||
<div class="cbi-value-title left"><%:a_s_flash_fwimage%></div>
|
<div class="cbi-value-title left"><%:a_s_flash_fwimage%></div>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<%+header%>
|
<%+header%>
|
||||||
<h1>404 Not Found</h1>
|
<h1>404 Not Found</h1>
|
||||||
<p>Sorry, the object you requested was not found.</p>
|
<p>Sorry, the object you requested was not found.</p>
|
||||||
<tt>Unable to dispatch: <%=luci.http.env.PATH_INFO%></tt>
|
<tt>Unable to dispatch: <%=luci.http.request.env.PATH_INFO%></tt>
|
||||||
<%+footer%>
|
<%+footer%>
|
|
@ -22,8 +22,8 @@ function action_index()
|
||||||
luci.http.prepare_content("text/plain")
|
luci.http.prepare_content("text/plain")
|
||||||
|
|
||||||
-- General
|
-- General
|
||||||
print("luciinfo.api=1")
|
luci.http.write("luciinfo.api=1\n")
|
||||||
print("luciinfo.version=" .. tostring(require("luci").__version__))
|
luci.http.write("luciinfo.version=" .. tostring(require("luci").__version__) .. "\n")
|
||||||
|
|
||||||
-- Sysinfo
|
-- Sysinfo
|
||||||
local s, m, r = luci.sys.sysinfo()
|
local s, m, r = luci.sys.sysinfo()
|
||||||
|
@ -31,14 +31,14 @@ function action_index()
|
||||||
dr = dr and luci.sys.net.hexip4(dr.Gateway) or ""
|
dr = dr and luci.sys.net.hexip4(dr.Gateway) or ""
|
||||||
local l1, l5, l15 = luci.sys.loadavg()
|
local l1, l5, l15 = luci.sys.loadavg()
|
||||||
|
|
||||||
print("sysinfo.system=" .. sanitize(s))
|
luci.http.write("sysinfo.system=" .. sanitize(s) .. "\n")
|
||||||
print("sysinfo.cpu=" .. sanitize(m))
|
luci.http.write("sysinfo.cpu=" .. sanitize(m) .. "\n")
|
||||||
print("sysinfo.ram=" .. sanitize(r))
|
luci.http.write("sysinfo.ram=" .. sanitize(r) .. "\n")
|
||||||
print("sysinfo.hostname=" .. sanitize(luci.sys.hostname()))
|
luci.http.write("sysinfo.hostname=" .. sanitize(luci.sys.hostname()) .. "\n")
|
||||||
print("sysinfo.load1=" .. tostring(l1))
|
luci.http.write("sysinfo.load1=" .. tostring(l1) .. "\n")
|
||||||
print("sysinfo.load5=" .. tostring(l5))
|
luci.http.write("sysinfo.load5=" .. tostring(l5) .. "\n")
|
||||||
print("sysinfo.load15=" .. tostring(l15))
|
luci.http.write("sysinfo.load15=" .. tostring(l15) .. "\n")
|
||||||
print("sysinfo.defaultgw=" .. dr)
|
luci.http.write("sysinfo.defaultgw=" .. dr .. "\n")
|
||||||
|
|
||||||
|
|
||||||
-- Freifunk
|
-- Freifunk
|
||||||
|
@ -46,7 +46,7 @@ function action_index()
|
||||||
for k, v in pairs(ff) do
|
for k, v in pairs(ff) do
|
||||||
for i, j in pairs(v) do
|
for i, j in pairs(v) do
|
||||||
if i:sub(1, 1) ~= "." then
|
if i:sub(1, 1) ~= "." then
|
||||||
print("freifunk." .. k .. "." .. i .. "=" .. j)
|
luci.http.write("freifunk." .. k .. "." .. i .. "=" .. j .. "\n")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<%
|
<%
|
||||||
require("luci.sys")
|
require("luci.sys")
|
||||||
local load1, load5, load15 = luci.sys.loadavg()
|
local load1, load5, load15 = luci.sys.loadavg()
|
||||||
local request = require("luci.dispatcher").request
|
local request = require("luci.dispatcher").context.path
|
||||||
local category = request[1]
|
local category = request[1]
|
||||||
local tree = luci.dispatcher.node()
|
local tree = luci.dispatcher.node()
|
||||||
local cattree = category and luci.dispatcher.node(category)
|
local cattree = category and luci.dispatcher.node(category)
|
||||||
local node = luci.dispatcher.dispatched
|
local node = luci.dispatcher.context.dispatched
|
||||||
|
|
||||||
local c = tree
|
local c = tree
|
||||||
for i,r in ipairs(request) do
|
for i,r in ipairs(request) do
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<%
|
<%
|
||||||
require("luci.sys")
|
require("luci.sys")
|
||||||
local load1, load5, load15 = luci.sys.loadavg()
|
local load1, load5, load15 = luci.sys.loadavg()
|
||||||
local request = require("luci.dispatcher").request
|
local request = require("luci.dispatcher").context.path
|
||||||
local category = request[1]
|
local category = request[1]
|
||||||
local tree = luci.dispatcher.node()
|
local tree = luci.dispatcher.node()
|
||||||
local cattree = category and luci.dispatcher.node(category)
|
local cattree = category and luci.dispatcher.node(category)
|
||||||
local node = luci.dispatcher.dispatched
|
local node = luci.dispatcher.context.dispatched
|
||||||
|
|
||||||
local c = tree
|
local c = tree
|
||||||
for i,r in ipairs(request) do
|
for i,r in ipairs(request) do
|
||||||
|
|
Loading…
Reference in a new issue