1. 页面请求:

1.1. 代码结构

在openwrt文件系统中,lua语言的代码不要编译,类似一种脚本语言被执行,还有一些uhttpd服务器的主目录,它们是:

/www/index.html

cgi-bin/luci

luci-static/xxx/xx.css、js、gif

/usr/lib/lua/nixio.so、uci.so

luci/http.lua、dispatcher.lua、core…

controller/xxx.lua

model/xxx.lua

view/xxx.lua

1.2. 界面显示

网页请求格式基本都如下所示:http://10.10.82.238/cgi-bin/luci,说明处理都在服务器的默认网站下的/cgi-bin/luci文件进行处理。

1.2.1.  /www/cgi-bin/luci

luci.dispatcher.indexcache = "/tmp/luci-indexcache"--缓存文件位置“/tmp/luci-indexcache”

luci.sgi.cgi.run()--cgi程序接下来执行程序,Luci的默认路径是/usr/lib/lua/luci,所以luci.sgi.cgi.run()是运行/usr/lib/lua/luci/sgi/cgi.lua文件中的run函数。

1.2.2. /usr/lib/lua/luci/sgi/cgi.lua

local r = luci.http.Request(…)--把web请求放于r中(包括环境变量,web请求,出错处理接口)

local x = coroutine.create(luci.dispatcher.httpdispatch)--创建一个协同程序

local res, id, data1, data2 = coroutine.resume(x, r)--运行上面创建的协同程序,即运行httpdispatch,参数为上面local r里的变量。

if active then

if id == 1 then

io.write("Status: " .. tostring(data1) .. " " .. data2 .. "\r\n")

elseif id == 2 then

hcache = hcache .. data1 .. ": " .. data2 .. "\r\n"—准备header

elseif id == 3 then--写header、blank

io.write(hcache)—默认到stdout

io.write("\r\n")

elseif id == 4 then

io.write(tostring(data1 or ""))--写body

elseif id == 5 then

io.flush()

io.close()--EOF

active = false

elseif id == 6 then

data1:copyz(nixio.stdout, data2)

data1:close()

1.2.3.  /usr/lib/lua/luci/dispatcher.lua

httpdispatch:解析请求,获得请求节点,并调用dispatch处理请求节点,如:

Request :http://10.10.82.238/cgi-bin/luci/;stok=e10fa5c70fbb55d478eb8b8a2eaabc6f/admin/network/firewall/      get: admin network firewall

dispatch:四个部分处理请求

A.节点树node-tree创立

if not c then

c = createtree()

B.需要显示的部分

if (c and c.index) or not track.notemplate then

C.认证

if track.sysauth then

D.显示/处理

ok, err = util.copcall(target, c.target, unpack(args))

1.2.4. 请求页面network

http://10.10.82.238/cgi-bin/luci/;stok=4b77c83a89c7b9cd8f4dcc0fcbc28024/admin/network/

1.2.3中D显示部分与entry()函数(形如entry(path,target,title,order))有关,其中定义的target方法或者target部分。在以上http请求中会根据请求路径去访问到/usr/lib/lua/luci/controller/admin/network.lua,调用顺序如下:

ok, err = util.copcall(target, unpack(args))-- dispatcher.luaà

page.target = firstchild() -- network.luaà

function firstchild()-- dispatcher.luaà

_firstchild()-- dispatcher.luaàdispatch(path)-- 自动链接到它的第一个子节点,

在network.lua中定义order,Interfaces是10,为第一个子节点:

page = entry({"admin", "network", "network"}, arcombine(cbi("admin_network/network"), cbi("admin_network/ifaces")), _("Interfaces"), 10)--通过cbi方法处理admin_network/ifaces.lua和admin_network/network.lua,生成html文件

2. 页面响应

2.1. Web请求

当点击页面“Save & Apply”按钮时,浏览器会把每一个有name的web元素的对应值下传,下传form表格如下:

-----------------------------151563007122428

Content-Disposition: form-data; name="cbi.submit" 1

-----------------------------151563007122428

Content-Disposition: form-data; name="cbi.cbe.firewall.cfg02e63d.syn_flood" 1 -----------------------------151563007122428

Content-Disposition: form-data; name="cbi.cbe.firewall.cfg02e63d.drop_invalid" 1

……

……

-----------------------------151563007122428

Content-Disposition: form-data; name="cbi.apply" Save & Apply -----------------------------151563007122428—

2.2. 处理

服务器处理过程和页面生成基本类似,也调用到/usr/lib/lua/luci/dispatcher.lua并走到显示/处理部分,后继处理如下:

ok, err = util.copcall(target, c.target, unpack(args)) à(target在luci/controller/firewall中被赋值为arcombine(cbi("firewall/zones"), cbi("firewall/zone-details")),即两个cbi函数的集合)

function cbi(model, config) à

local function _cbi(self, ...) à

local cstate = res:parse()à

function Map.parse(self, readinput, ...) à

Node.parse(self, ...)

Node.parse会调用Map中的每一个子元素自身的处理

EX:

如调用Flag的处理:function Flag.parse(self, section),他会通过遍历处理from传下来的每一个Flag,并通过本身的write/remove来启用和禁用这个选项。

当form保存下来cbid.firewall.cfg02e63d.syn_flood这个Network/Firewall/General Setting下的Flag标签的值时,处理函数就会调用Flag.parse处理:调用self:formvalue来匹配标签值,然后调用model/cbi/firewall/zones.lua的write或者remove来禁用或者启用这个选项所控制的开关。

由于Flag = class(AbstractValue),继承于AbstractValue类,所以其write/remove是调用的AbstractValue类的write/remove方法。

AbstractValue.write调用self.map:set即function Map.set(self, section, option, value),Map.set 再调用self.uci:set(self.config, section, option, value)来设置对应config文件,然后Map.parse 会调用self.uci:commit(config)对已修改的config逐一提交。

生效的两种方式

1、按照固定格式设置对应选项,系统自动调用来使各个参数生效,self.uci:apply(self.parsechain) (应用刚设置的config设置服务)àfunction Cursor.apply(self, configlist, command) àreturn { "/sbin/luci-reload", unpack(configlist) };

2、self:_run_hooks("on_apply", "on_after_apply"),自己在对应的.lua文件中写m.on_apply来启动或者处理方式。

ps:openwrt个人理解加上前辈的blog来写的,基本是一路打log来了解流程,若有文中问题还请指正

参考:http://www.verydemo.com/demo_c101_i48675.html

Luci流程分析(openwrt下)的更多相关文章

  1. openwrt luci web分析

    openwrt luci web分析 来源 https://www.jianshu.com/p/596485f95cf2 www/cbi-bin/luci #!/usr/bin/lua --cgi的执 ...

  2. freeswitch呼叫流程分析

    今天翻文档时发现之前整理的关于freeswitch呼叫相关的内容,写成博文分享出来也方便我以后查阅. 整体结构图 FreeswitchCore 模块加载过程 freeswitch主程序初始化时会从mo ...

  3. u-boot 流程分析

    u-boot 介绍: 对于计算机来说 , 从一开始上机通电是无法直接启动操作系统的 , 这中间需要一个引导过程 , 嵌入式Linux系统同样离不开引导程序 ,  这个启动程序就叫启动加载程序(Boot ...

  4. thttpd和cgilua安装与运行流程分析

    安装 参考如下博文安装thttpd软件 http://blog.csdn.net/21aspnet/article/details/7045845 http://blog.csdn.net/drago ...

  5. u-boot中nandflash初始化流程分析(转)

    u-boot中nandflash初始化流程分析(转) 原文地址http://zhuairlunjj.blog.163.com/blog/static/80050945201092011249136/ ...

  6. Android7.0 Phone应用源码分析(二) phone来电流程分析

    接上篇博文:Android7.0 Phone应用源码分析(一) phone拨号流程分析 今天我们再来分析下Android7.0 的phone的来电流程 1.1TelephonyFramework 当有 ...

  7. 从注册流程 分析如何安全退出多个Activity 多种方式(附DEMO)

      退出Activity注册Android遍历   目录(?)[+] 前言 知识结构 具体方案 方案1 方法采用FLAG_ACTIVITY_CLEAR_TOP退出整个程序多activity 方案2 方 ...

  8. ofbiz进击 。 ofbiz 退货流程(包含获取可退货项流程分析 以及 取消退货项的过程分析)

    根据订单获取可退货项流程分析 退货的时候,调用 services_return.xml 中的获取可进行退货的退货项  getReturnableItems  ,该服务调用了Java类 org.ofbi ...

  9. u-boot启动流程分析(2)_板级(board)部分

    转自:http://www.wowotech.net/u-boot/boot_flow_2.html 目录: 1. 前言 2. Generic Board 3. _main 4. global dat ...

随机推荐

  1. QWidget: Must construct a QApplication before a QPaintDevice的问题

    卧槽,无意中编译自己基于Qt创建的Debug工程的时候运行时发生了标题中的错误,原来是把Qt Release的库也放到additional dependencies里面了,同时链接了Debug和Rel ...

  2. centos 6.4 更新源地址

    执行如下命令: mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.old vim /etc/yum.repo ...

  3. RBL, UBL, Uboot的关系

    RBL, UBL, Uboot的关系 1)RBL=ROM Bootloader,UBL=user Bootloader. 2)RBL为TI固化在芯片ROM中的bootloader,OMAP上电启动过后 ...

  4. 认识什么是SEO

    何为SEO? SEO是由英 文Search Engine Optimization缩写而来, 中文意译为“搜索引擎优化”,是指在了解搜索引擎自然排名机制的基础上,对网站进行内部及外部的调整优化,改进网 ...

  5. [转载]Linux编程 sockaddr_in 和sockaddr和in_addr详解

    sockaddr sockaddr 是通用的socket地址,具体到Internet socket,用下面的结构,二者可以进行类型转换 sa_family是地址家族,一般都是"AF_xxx& ...

  6. 第14/15讲- Android资源管理

    第14/15讲 Android资源管理 Android中的资源是指非代码部分,比如图片.MP3,字符串,XML文件等.在一个android工程中,res和assets是用来保存资源文件的. res和a ...

  7. Arm Linux系统调用流程详细解析

    Linux系统通过向内核发出系统调用(system call)实现了用户态进程和硬件设备之间的大部分接口. 系统调用是操作系统提供的服务,用户程序通过各种系统调用,来引用内核提供的各种服务,系统调用的 ...

  8. 腾讯TT浏览器应用程序发生异常(0xc0000409) 位置为0x027a1f7f 的解决办法

    2013年8月26日下午,腾讯TT浏览器 4.8版1000 出现“应用程序发生异常(0xc0000409)  位置为0x027a1f7f ”的错误,导致浏览器自动关闭. 无论重新卸载安装还是 清理系统 ...

  9. OCR怎么能离开扫描仪呢?

    说起OCR,说来说去就是和各种各样的图片打交道. 所以图片的质量很的关键. 说起图片的质量,不得不提的就是图片的採集. 眼下最靠谱的图像採集来源就是扫描仪. 扫描仪的话就大有说法,最靠谱的扫描仪,扫描 ...

  10. Impala与Hive的比較

    1. Impala架构        Impala是Cloudera在受到Google的Dremel启示下开发的实时交互SQL大数据查询工具,Impala没有再使用缓慢的Hive+MapReduce批 ...