module("ffluci.dispatcher", package.seeall)
require("ffluci.http")
require("ffluci.template")
+require("ffluci.config")
+require("ffluci.sys")
+-- Sets privilege for given category
+function assign_privileges(category)
+ local cp = ffluci.config.category_privileges
+ if cp and cp[category] then
+ local u, g = cp[category]:match("([^:]+):([^:]+)")
+ ffluci.sys.process.setuser(u)
+ ffluci.sys.process.setgroup(g)
+ end
+end
+
-- Dispatches the "request"
function dispatch(req)
request = req
return error404()
else
module.request = request
+ module.dispatcher = module.dispatcher or dynamic
setfenv(module.dispatcher, module)
return module.dispatcher(request)
end
function error404(message)
message = message or "Not Found"
- local s, t = pcall(ffluci.template.Template, "error404")
-
- if not s then
+ if not pcall(ffluci.template.render, "error404") then
ffluci.http.textheader()
print(message)
- else
- t:render()
end
return false
end
function error500(message)
ffluci.http.status(500, "Internal Server Error")
- local s, t = pcall(ffluci.template.Template, "error500")
-
- if not s then
+ if not pcall(ffluci.template.render, "error500", {message=message}) then
ffluci.http.textheader()
print(message)
- else
- t:render()
end
return false
end
local mod = sanitize(parts(), "index")
local act = sanitize(parts(), "index")
+ assign_privileges(cat)
dispatch({category=cat, module=mod, action=act})
end
--- The Simple View Dispatcher directly renders the template
--- which is placed in ffluci/views/"request.module"/"request.action"
-function simpleview(request)
+
+-- Dispatchers --
+
+
+-- The Action Dispatcher searches the module for any function called
+-- action_"request.action" and calls it
+function action(request)
local i18n = require("ffluci.i18n")
- local tmpl = require("ffluci.template")
local disp = require("ffluci.dispatcher")
i18n.loadc(request.module)
- local s, t = pcall(tmpl.Template, request.module .. "/" .. request.action)
-
- if not s then
+ local action = getfenv()["action_" .. request.action:gsub("-", "_")]
+ if action then
+ action()
+ else
disp.error404()
+ end
+end
+
+-- The CBI dispatcher directly parses and renders the CBI map which is
+-- placed in ffluci/modles/cbi/"request.module"/"request.action"
+function cbi(request)
+ local i18n = require("ffluci.i18n")
+ local disp = require("ffluci.dispatcher")
+ local tmpl = require("ffluci.template")
+ local cbi = require("ffluci.cbi")
+
+ local path = request.category.."_"..request.module.."/"..request.action
+
+ i18n.loadc(request.module)
+
+ local stat, map = pcall(cbi.load, path)
+ if stat and map then
+ local stat, err = pcall(map.parse, map)
+ if not stat then
+ disp.error500(err)
+ return
+ end
+ tmpl.render("cbi/header")
+ map:render()
+ tmpl.render("cbi/footer")
+ elseif not stat then
+ disp.error500(map)
else
- t:render()
+ disp.error404()
end
end
--- The Action Dispatcher searches the module for any function called
--- action_"request.action" and calls it
-function action(request)
+-- The dynamic dispatchers combines the action, simpleview and cbi dispatchers
+-- in one dispatcher. It tries to lookup the request in this order.
+function dynamic(request)
local i18n = require("ffluci.i18n")
local disp = require("ffluci.dispatcher")
+ local tmpl = require("ffluci.template")
+ local cbi = require("ffluci.cbi")
i18n.loadc(request.module)
+
local action = getfenv()["action_" .. request.action:gsub("-", "_")]
if action then
action()
- else
+ return
+ end
+
+ local path = request.category.."_"..request.module.."/"..request.action
+ if pcall(tmpl.render, path) then
+ return
+ end
+
+ local stat, map = pcall(cbi.load, path)
+ if stat and map then
+ local stat, err = pcall(map.parse, map)
+ if not stat then
+ disp.error500(err)
+ return
+ end
+ tmpl.render("cbi/header")
+ map:render()
+ tmpl.render("cbi/footer")
+ return
+ elseif not stat then
+ disp.error500(map)
+ return
+ end
+
+ disp.error404()
+end
+
+-- The Simple View Dispatcher directly renders the template
+-- which is placed in ffluci/views/"request.module"/"request.action"
+function simpleview(request)
+ local i18n = require("ffluci.i18n")
+ local tmpl = require("ffluci.template")
+ local disp = require("ffluci.dispatcher")
+
+ local path = request.category.."_"..request.module.."/"..request.action
+
+ i18n.loadc(request.module)
+ if not pcall(tmpl.render, path) then
disp.error404()
end
end
\ No newline at end of file