Luci流程分析(openwrt下)

2021-09-07 00:14:50 字數 4048 閱讀 7688

在openwrt檔案系統中,lua語言的**不要編譯,類似一種指令碼語言被執行,還有一些uhttpd伺服器的主目錄,它們是:

網頁請求格式基本都如下所示:說明處理都在伺服器的預設**下的/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函式。

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()

httpdispatch:解析請求,獲得請求節點,並呼叫dispatch處理請求節點,如:

request :      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.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,inte***ces是10,為第乙個子節點:

page = entry(, arcombine(cbi("admin_network/network"), cbi("admin_network/ifaces")), _("inte***ces"), 10)--通過cbi方法處理admin_network/ifaces.lua和admin_network/network.lua,生成html檔案

-----------------------------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

伺服器處理過程和頁面生成基本類似,也呼叫到/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逐一提交。

生效的兩種方式

ps:openwrt個人理解加上前輩的blog來寫的,基本是一路打log來了解流程,若有文中問題還請指正

參考:

OpenWRT 修改LuCI 語言 主題

前陣子自己在ubuntu中編譯了乙個openwrt系統,並將.bin韌體刷入到了wr703n中 但是,當時編譯韌體時,沒有設定luci,全部都是預設值。當將韌體刷入後,登陸web介面配置路由器時,發現介面不美觀 並且是英文的。前天,公司同事告知,其實可以將luci語言和主題設成中文和不同的主題,說重...

手動編譯LUCI 到 openwrt中

分類 openwrt 2013 11 15 17 16 1215人閱讀收藏 舉報 之前編譯的openwrt一直都沒有介面需要手動安裝介面,其實手動安裝介面很簡單,只需要簡單的三個步驟即可 首先,telnet進入路由器 telnet 192.168.1.1.此時會看到openwrt的歡迎介面 然後,更...

修改openwrt的配置介面luci的方法

也許你想修改一下openwrt那個路由配置的醜陋介面,也許你想事項自己軟體的一些功能。但是卻沒有辦法去修改luci。在路由器上直接修改那就算了,我想說的是如何修改該luci的源 這樣子你編譯好的bin映象檔案直接刷入路由器中就ok了。你先得了解一下luci,包括它的模組怎麼寫的,用的是lua語言等 ...