Luci流程分析(openwrt下)

转自:http://blog.chinaunix.net/uid-23780428-id-4367414.html

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

时间: 2024-12-05 20:46:59

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

openwrt luci web分析

openwrt luci web分析 来源 https://www.jianshu.com/p/596485f95cf2 www/cbi-bin/luci #!/usr/bin/lua --cgi的执行命令的路径 require"luci.cacheloader" --导入cacheloader包 require"luci.sgi.cgi" --导入sgi.cgi包 luci.dispatcher.indexcache = "/tmp/luci-index

OpenWRT下web框架初尝试之总结

OpenWRT下web总结 目  录 目  录 1 第一章 Web框架以及实现 2 第一节 luci框架 2 第二节 controller下文件(*.lua)的编写 2 第三节 model下文件(*.lua)编写 3 第四节 view下文件(*.htm)编写 4 第二章 web的访问流程 5 第三章 lua学习资料 6 参考资料 7 第一章 Web框架以及实现 第一节 luci框架 OpenWRT的web采用的是luci框架,该框架采用了MVC的设计模式.在luci目录下有三个重要的目录:con

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

安装 参考如下博文安装thttpd软件 http://blog.csdn.net/21aspnet/article/details/7045845 http://blog.csdn.net/dragoncheng/article/details/5614559 thttpd配置文件: [email protected]:/usr/local/bin# cat /usr/local/thttpd/conf/ etc/  logs/ man/  sbin/ www/  [email protecte

U-Boot移植之前期分析(下)

接U-Boot移植之前期分析(上): 2. 顶层目录下mkconfig的分析过程 在上面的分析中知道了语句:"@$(MKCONFIG) $(@:_config=) arm arm920t MY_JZ2440 sumsung s3c24x0"对应于执行顶层目录下的mkconfig文件并传递了六个参数 ($0-$6):100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0.下面分析这句话的到底做了什么事情,具体可以阅读源码,由于比较简单这里直接列出具体

Linux系统启动流程分析与关机流程

Linux 系统启动流程分析 Linux系统的启动过程并不是大家想象中的那么复杂,其过程可以分为5个阶段: 内核的引导. 运行 init. 系统初始化. 建立终端. 用户登录系统. init程序的类型: SysV: init, CentOS 5之前, 配置文件: /etc/inittab. Upstart: init,CentOS 6, 配置文件: /etc/inittab, /etc/init/*.conf. Systemd: systemd, CentOS 7,配置文件: /usr/lib/

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

转自:http://www.wowotech.net/u-boot/boot_flow_2.html 目录: 1. 前言 2. Generic Board 3. _main 4. global data介绍以及背后的思考 5. 前置的板级初始化操作 6. u-boot的relocation 7. 后置的板级初始化操作 1. 前言 书接上文(u-boot启动流程分析(1)_平台相关部分),本文介绍u-boot启动流程中和具体版型(board)有关的部分,也即board_init_f/board_i

Cocos2d-x3.3RC0的Android编译Activity启动流程分析

本文将从引擎源代码Jni分析Cocos2d-x3.3RC0的Android Activity的启动流程,以下是具体分析. 1.引擎源代码Jni.部分Java层和C++层代码分析 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXV4aWt1b18x/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" > watermark/2/text/aHR0cDov

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

前言 由于一个同学问到我如何按照一个流程走好之后回到首页,我以前看到过4个解决方案,后来发现有做个记录和总结的必要,就写了这篇博文.(之前看小强也写过一篇,这里通过自身的分析完整的总结一下以下6种方案,并加上一个DEMO便于大家了解大体流程) 在android的用户交互中,按钮触发的意图(Intent)跳转会为你重新打开新的一个界面活动(Activity),对于之前的界面根据需求进行摧毁(Finish())或则保留. 如果一个交互流程中,是从A开始,按照A - B - C - D - A这样的顺

基于linux与busybox的reboot命令流程分析

http://www.xuebuyuan.com/736763.html 基于Linux与Busybox的Reboot命令流程分析 *************************************************************************************************************************** 作者:EasyWave