* Fixed haserl-lua Makefile
[project/luci.git] / src / ffluci / dispatcher.lua
index f43d7f5..b60a9be 100644 (file)
@@ -84,8 +84,20 @@ limitations under the License.
 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
@@ -95,21 +107,19 @@ function dispatch(req)
                return error404()
        else
                module.request = request
+               module.dispatcher = module.dispatcher or dynamic
                setfenv(module.dispatcher, module)
                return module.dispatcher(request)
        end     
 end
 
-
 -- Sends a 404 error code and renders the "error404" template if available
 function error404(message)
        message = message or "Not Found"
        
-       ffluci.http.status(404, "Not Found")
-       
        if not pcall(ffluci.template.render, "error404") then
                ffluci.http.textheader()
-               print(message)          
+               print(message)
        end
        return false    
 end
@@ -118,7 +128,7 @@ end
 function error500(message)
        ffluci.http.status(500, "Internal Server Error")
        
-       if not pcall(ffluci.template.render, "error500") then
+       if not pcall(ffluci.template.render, "error500", {message=message}) then
                ffluci.http.textheader()
                print(message)
        end
@@ -139,37 +149,109 @@ function httpdispatch()
        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 conf = require("ffluci.config")
        local disp = require("ffluci.dispatcher")
        
-       pcall(i18n.load, request.module .. "." .. conf.lang)
-       if not pcall(tmpl.get, request.module .. "/" .. request.action) then
+       i18n.loadc(request.module)
+       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
-               tmpl.render(request.module .. "/" .. request.action)
+               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 conf = require("ffluci.config")
        local disp = require("ffluci.dispatcher")
+       local tmpl = require("ffluci.template")
+       local cbi  = require("ffluci.cbi")      
+       
+       i18n.loadc(request.module)
        
-       pcall(i18n.load, request.module .. "." .. conf.lang)
        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