Luci的工作流程

1、浏览器敲入192.168.1.1后就,路由器作为uhttp server会把/www/index.html这个页面返回给浏览器,而且这个页面又会刷新, 去请求页面/luci/cgi,代码如红色标记:

<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 下面的菜单。这样既有效的管理了不同管理员的权限。


  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值