Tuned dispatcher behaviour
[project/luci.git] / libs / web / luasrc / dispatcher.lua
index 3805f5c..8e8e190 100644 (file)
@@ -112,11 +112,14 @@ function httpdispatch(request)
        end
        
        luci.http.close()
+
+       --context._disable_memtrace()
 end
 
 --- Dispatches a LuCI virtual path.
 -- @param request      Virtual path
 function dispatch(request)
+       --context._disable_memtrace = require "luci.debug".trap_memtrace()
        local ctx = context
        ctx.path = request
        
@@ -160,9 +163,10 @@ function dispatch(request)
        -- Init template engine
        if not track.notemplate then
                local tpl = require("luci.template")
-               local viewns = {}
+               local viewns = setmetatable({}, {__index=_G})
                tpl.context.viewns = viewns
                viewns.write       = luci.http.write
+               viewns.include     = function(name) tpl.Template(name):render(getfenv(2)) end
                viewns.translate   = function(...) return require("luci.i18n").translate(...) end
                viewns.striptags   = util.striptags
                viewns.controller  = luci.http.getenv("SCRIPT_NAME")
@@ -171,6 +175,7 @@ function dispatch(request)
                viewns.REQUEST_URI = (luci.http.getenv("SCRIPT_NAME") or "") .. (luci.http.getenv("PATH_INFO") or "")
        end
        
+       track.dependent = (track.dependent ~= false)
        assert(not track.dependent or not track.auto, "Access Violation")
        
        if track.sysauth then
@@ -182,7 +187,7 @@ function dispatch(request)
                 
                local def  = (type(track.sysauth) == "string") and track.sysauth
                local accs = def and {track.sysauth} or track.sysauth
-               local sess = luci.http.getcookie("sysauth")
+               local sess = ctx.authsession or luci.http.getcookie("sysauth")
                sess = sess and sess:match("^[A-F0-9]+$")
                local user = sauth.read(sess)
                
@@ -197,6 +202,7 @@ function dispatch(request)
                                        if not sess then
                                                sauth.write(sid, user)
                                        end
+                                       ctx.authsession = sid
                                end
                        else
                                luci.http.status(403, "Forbidden")
@@ -217,7 +223,15 @@ function dispatch(request)
                context.dispatched = c
                
                util.copcall(function()
-                       util.updfenv(c.target, require(c.module))
+                       local oldenv = getfenv(c.target)
+                       local module = require(c.module)
+                       local env = setmetatable({}, {__index=
+                               
+                       function(tbl, key)
+                               return rawget(tbl, key) or module[key] or oldenv[key] 
+                       end})
+
+                       setfenv(c.target, env)
                end)
                
                c.target(unpack(args))
@@ -263,6 +277,13 @@ function createindex_plain(path, suffix)
        if indexcache then
                local cachedate = fs.mtime(indexcache)
                if cachedate and cachedate > fs.mtime(path) then
+
+                       assert(
+                               sys.process.info("uid") == fs.stat(indexcache, "uid")
+                               and fs.stat(indexcache, "mode") == "rw-------",
+                               "Fatal: Indexcache is not sane!"
+                       )
+
                        index = loadfile(indexcache)()
                        return index
                end             
@@ -287,6 +308,7 @@ function createindex_plain(path, suffix)
        
        if indexcache then
                fs.writefile(indexcache, util.get_bytecode(index))
+               fs.chmod(indexcache, "a-rwx,u+rw")
        end
 end
 
@@ -306,12 +328,7 @@ function createtree()
        -- Load default translation
        require "luci.i18n".loadc("default")
        
-       local scope = setmetatable({}, {__index = _G})
-       for k,v in pairs(luci.dispatcher) do
-               if type(v) == "function" then
-                       scope[k] = v
-               end
-       end
+       local scope = setmetatable({}, {__index = luci.dispatcher})
 
        for k, v in pairs(index) do
                scope._NAME = k
@@ -335,17 +352,8 @@ function assign(path, clone, title, order)
        
        obj.title = title
        obj.order = order
-       
-       local c = context.tree
-       for k, v in ipairs(clone) do
-               if not c.nodes[v] then
-                       c.nodes[v] = {nodes={}}
-               end
 
-               c = c.nodes[v]
-       end
-       
-       setmetatable(obj, {__index = c})
+       setmetatable(obj, {__index = _create_node(clone)})
        
        return obj
 end
@@ -371,7 +379,7 @@ end
 -- @param      ...             Virtual path
 -- @return                     Dispatching tree node
 function node(...)
-       local c = _create_node(arg)
+       local c = _create_node({...})
 
        c.module = getfenv(2)._NAME
        c.path = arg
@@ -456,18 +464,10 @@ function cbi(model)
                require("luci.cbi")
                require("luci.template")
 
-               local stat, maps = luci.util.copcall(luci.cbi.load, model, ...)
-               if not stat then
-                       error500(maps)
-                       return true
-               end
+               maps = luci.cbi.load(model, ...)
 
                for i, res in ipairs(maps) do
-                       local stat, err = luci.util.copcall(res.parse, res)
-                       if not stat then
-                               error500(err)
-                               return true
-                       end
+                       res:parse()
                end
 
                luci.template.render("cbi/header")
@@ -485,18 +485,10 @@ function form(model)
                require("luci.cbi")
                require("luci.template")
 
-               local stat, maps = luci.util.copcall(luci.cbi.load, model, ...)
-               if not stat then
-                       error500(maps)
-                       return true
-               end
+               maps = luci.cbi.load(model, ...)
 
                for i, res in ipairs(maps) do
-                       local stat, err = luci.util.copcall(res.parse, res)
-                       if not stat then
-                               error500(err)
-                               return true
-                       end
+                       res:parse()
                end
 
                luci.template.render("header")