uhttpd + Fast-CGI的開發要求:
- 安裝uhttpd包(https需要加裝“uhttpd-mod-tls”和“px5g”);
- 修改uhttpd配置文件“/etc/config/uhttpd”,將Lua作爲“interpreter”;
- Lua腳本寫到“/www/cgi-bin/”目錄下,但是不帶擴展名,且可執行;
- Fast-CGI要求Lua腳本必須首先使用“io.write()”輸出“Content-type: text/html\n\n”;
- “/www/cgi-bin/”目錄下的腳本可以調用“/usr/lib/lua/”目錄下的自定義模塊;
- Lua環境已經就緒。
以“讀取GET和POST數據”爲例,全部使用默認值的情況下,如何具體實現:
第一步:使用“opkg update”更新“.ipk”包的源,然後使用“opkg install uhttpd”安裝;
第二步:使用“vi /etc/config/uhttpd”,在“config uhttpd main”下添加一行
list interpreter ".lua=/usr/bin/lua”
第三步:建立目錄“/www/cgi-bin”,並增加“+x”屬性;
root@OpenWrt:~# mkdir -p /www/cgi-bin/
root@OpenWrt:~# chmod +x /www/cgi-bin/
建立響應文件,並增加“+x”屬性;
root@OpenWrt:~# touch /www/cgi-bin/webservice
root@OpenWrt:~# chmod +x /www/cgi-bin/webservice
將文件“/www/cgi-bin/webservice”內容修改爲:
#!/usr/bin/lua
local WebService = require 'WebService'
WebService.Run()
第四步:建立Lua模塊文件(不再要求“+x”屬性),並讀取參數,返回響應:
root@OpenWrt:~# touch /usr/lib/lua/WebService.lua
將其內容修改爲如下內容:
local WebService = {}
function WebService.Run()
local client = os.getenv("REMOTE_ADDR")
local GET = os.getenv("QUERY_STRING")
local POST = nil
local POSTLength = tonumber(os.getenv("CONTENT_LENGTH")) or 0
if (POSTLength > 0) then
POST = io.read(POSTLength)
--POST = io.read("*a")
end
-- Fast-CGI+HTTP require HEADER
-- enable cache
--io.write("Content-type: text/html\n\n")
-- disable cache, especially for Internet Explorer
io.write("Content-type: text/html\nPragma: no-cache\n\n")
local reply = string.format("Client %s said: url: [%s], data: [%s]\n", client or '-', GET or '-', POST or '-')
io.write(reply)
end
return WebService
第五步:重啓“uhttpd”服務(爲了讓更改的/etc/config/uhttpd生效):
root@OpenWrt:~# /etc/init.d/uhttpd restart
第六步:使用瀏覽器測試:
使用瀏覽器訪問如下地址:
http://<openwrt_ipaddr>/cgi-bin/webservice?author=qige
這裏假設OpenWrt開發板的IP爲192.168.1.24:
http://192.168.1.24/cgi-bin/webservice?author=qige
最終效果如下圖:
通過cUrl模擬POST提交通過form表單POST提交的瀏覽器結果
注意:
- POST數據可以由curl、Python requests等進行模擬提交,也可以自制如:<form action="/cgi-bin/webservice" method="POST">提交;
- 根據Fast-CGI要求,必須要先使用“io.write()”輸出http協議頭部;再根據http協議的要求,頭部和內容之間必須使用“\n\n”來隔開。因此Lua腳本必須先輸出頭部“Content-type: text/html\n\n”,再輸出其它內容;
- 如果“不需要緩存”,輸出立即過期,則修改頭部內容爲“Content-type: text/html\nPragma: no-cache\n\n”;
- 讓uhttpd開機自動啓動,需要執行“/etc/init.d/uhttpd enable”;
- 需要將接收到的數據輸出到串口,可以再安裝一個“coreutils-stty”包用於控制串口波特率
root@OpenWrt:~# opkg install coreutils
root@OpenWrt:~# opkg install coreutils-stty
再將以下內容添加到Lua模塊的適當位置,並調用此函數即可:
function WebService.uartWrite(msg)
local uartConfig = 'stty -F /dev/ttyS0 raw speed 9600\n'
os.execute(uartConfig)
local cmd = string.format("echo '%s' > /dev/ttyS0\n", msg or '')
os.execute(cmd)
end
轉自: https://www.zhihu.com/question/31579325/answer/283425839