<metahttp-equiv="refresh" content="0; URL=/cgi-bin/luci" />
</head>
<bodystyle="background-color: black">
<astyle="color: white; text-decoration: none"href="/cgi-bin/luci">LuCI - Lua Configuration Interface</a>
2.然后uhttp server就会去调用/www/cgi-bin/luci这上脚本,这个脚本的代码如下:
#!/usr/bin/lua
require"luci.cacheloader"
require"luci.sgi.cgi"
luci.dispatcher.indexcache= "/tmp/luci-indexcache"
luci.sgi.cgi.run() //最后一行开始解析http的请求。
我们可以到找到文件 usr/lib/lua/luci/sgi/cgi.lua,并找到run方法,这run 方法的主要任务就是在安全的环境中打开开始页面(登录页面 ) ,在 run 中,最主要的
功能还是在 dispatch.lua 中完成。
run方法代码如下:
local r = luci.http.Request(
luci.sys.getenv(),
limitsource(io.stdin,tonumber(luci.sys.getenv("CONTENT_LENGTH"))),
ltn12.sink.file(io.stderr)
)
local x =coroutine.create(luci.dispatcher.httpdispatch)
local hcache = ""
local active = true
while coroutine.status(x) ~="dead" do
local res, id, data1, data2 =coroutine.resume(x, r)
运行 luci 之后,就会出现登录界面:
-bash-4.0# pwd
/var/www/cgi-bin
-bash-4.0# ./luci
Status: 200 OK
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache
Expires: 0
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html class=" ext-strict"><head>
/*some html code*/
</html>
如果你成功的运行了 luci 就说明你的 luci 框架成功的跑了起来
luci.http.Request这个方法用来初始化一个http请求,并返回给变量r.接下来利用函数coroutine.create()创建一个协进程x,协进程的处理函数是luci.dispatcher,httpdispatch,接下来再使用函数coroutine.resume(x, r)激活协进程,并往协进程传值r,r就是我们的http请求。
现在我们打开luci/dispatcher.lua这个文件,并找到httpdispatch这个函数,代码如下:
functionhttpdispatch(request, prefix)
luci.http.context.request = request
local r = {}
context.request = r
context.urltoken = {}
local pathinfo =http.urldecode(request:getenv("PATH_INFO") or "", true)
if prefix then
for _, node in ipairs(prefix) do
r[#r+1] = node
end
end
local tokensok = true
for node inpathinfo:gmatch("[^/]+") do
local tkey, tval
if tokensok then
tkey, tval =node:match(";(%w+)=([a-fA-F0-9]*)")
end
if tkey then
context.urltoken[tkey]= tval
else
tokensok = false
r[#r+1] = node
end
end
local stat, err =util.coxpcall(function()
dispatch(context.request)
end, error500)
luci.http.close()
--context._disable_memtrace()
end
httpdispatch第一个参数就是coroutine.resume(x,r)传过来的请求r, prefix为空。httpdispatch的主要功能是从环境变量PATH_INFO获取请求路径,像字串”http://192.168.1.1/cgi-bin/luci/;stok=e10fa5c70fbb55d478eb8b8a2eaabc6f/admin/network/firewall/”,并把这个字符串解析成单个字符存放在table r{}中,最后再调用dispatch()这个函数,解析完后,关闭http连接。dispatch这个函数是整个LuCI中的核心。由于dispatch函数的代码太多,就不全部贴出来,只贴出一些关键步骤。
其中包含控件的添加和业务的处理, 其中alias cgi form call template等定义了此菜单相应的处理方式,form 和 cgi 对应到 model/cbi 相应的目
录下面,那里面是对应的定制好的 html 和 lua 业务处理。
主要目录的跳转如下:
1、/www/index.html
2、/luci/cgi
3、/www/cgi-bin/luci //注意此时的浏览器中的地址后缀与此相似4、usr/lib/lua/luci/sgi/cgi.lua //run的方法,登陆界面由此产生
5、luci/dispatcher.lua中的 httpdispatch函数,协进程的处理函数是luci.dispatcher.httpdispatch
httpdispatch的主要功能是从环境变量PATH_INFO获取请求路径,像字串”http://192.168.1.1/cgi-bin/luci/;stok=e10fa5c70fbb55d478eb8b8a2eaabc6f/admin/network/firewall/”,并把这个字符串解析成单个字符存放在table r{}中,最后再调用dispatch()这个函数,解析完后,关闭http连接。dispatch这个函数是整个LuCI中的核心。
然后介绍一下luci的MVC架构:
/usr/lib/lua/luci/,在底下主要有以下这些目录:model,controller,view解释如下:
LuCI是基于MVC的思想,基中M是model,是原来存取数据的地方, V就是view,原来向用户展示的页面, C就是controller, controller会从model中存取数据,并传给view,向用户展示配置结果。
在 luci 的官方网站说明了 luci 是一个 MVC 架构的框架,这个 MVC 做的可扩展性很好,可以完全的统一的写自己的 html 网页,而且他对 shell 的支持相当的到位, (因为 luci
是 lua 写的, lua 是 C 的儿子嘛, 与 shell 是兄弟) 。 在登录界面用户名的选择很重要,luci 是一个单用户框架,公用的模块放置在 */luci/controller/下面,各个用户的模块放置在*/luci/controller/下面对应的文件夹里面, 比如 admin 登录, 最终的页面只显示/luci/controller/admin 下面的菜单。这样既有效的管理了不同管理员的权限。