LuCI的RPC接口使用方法详解

LuCI的RPC接口使用方法详解

说明:这篇文章的部分内容来自于LuCI Wiki:http://luci.subsignal.org/trac/wiki/Documentation/JsonRpcHowTo,本文只是添加了一些示例和说明。
        LuCI是一个基于Lua语言开发的Web framework,提供UCI(统一配置接口)的web接口。LuCI也提供了一种基于JSON语法的RPC机制来访问其内部的库。当前LuCI提供了5个库的接口,分别是:auth、uci、fs、sys、ipkg。下面简单介绍一下使用方法,以及如何通过官方文档来构造json请求数据

AUTH库

        认证过程是所有其他操作的前提,因为其他操作都需要auth认证成功后产生的token,否则会返回403错误。我们来看一下auth过程是怎么样的。下文所有RPC的操作都是使用curl工具。

$ curl -i -X POST -d '{"method":"login","params":["root","1"]}' http://192.168.1.10:8080/luci/rpc/auth
HTTP/1.1 200 OK
Server: LuCId-HTTPd/1.0
Expires: 0
Content-Type: application/json
Cache-Control: no-cache
Date: Mon, 17 Mar 2014 17:27:30 GMT
Set-Cookie: sysauth=72fe65ae2dd4c8e77623576faba4ac4c; path=/
Connection: close

{"id":null,"result":"72fe65ae2dd4c8e77623576faba4ac4c","error":null}

简单说明一下,上面的命令是使用curl工具通过POST方式发送了一个http请求,请求的内容是一个登陆请求

{"method":"login","params":["root","1"]}

http返回的内容是json格式的字符串,其中result的值就是上面提到了token。OK,现在我们拿到了下面其他操作需要的关键字段TOKEN


另外,需要注意的是,LuCI在openwrt里的网址是:http://192.168.1.10/cgi-bin/luci/rpc/xxx,多了一个cgi-bin。这是因为openwrt默认使用uhttpd作为web server。而在PC里使用make runhttpd启动的是lua web server。

SYS库

        sys库提供了一下系统通用功能,比如说:执行一条命令,查看系统信息,重启等。具体功能请猛戳这个链接:http://luci.subsignal.org/api/luci/modules/luci.sys.html

这里找一个最简单来演示一下如何使用官方文档构造json数据,查看uptime时间。首先,我们看一下sys.uptime的官网说明:

uptime ()
    Returns the current system uptime stats.
    Return value:
    String containing total uptime in seconds 
uptime函数返回一个设备从上电到现在的总时间(秒)。那么,看一下使用HTTP请求来调这个函数的方法,还是curl模拟:

curl -i -X POST -d '{"method":"uptime"}' http://192.168.1.10:8080/luci/rpc/sys?auth=72fe65ae2dd4c8e77623576faba4ac4c
HTTP/1.1 200 OK
Server: LuCId-HTTPd/1.0
Expires: 0
Content-Type: application/json
Cache-Control: no-cache
Date: Mon, 17 Mar 2014 17:49:42 GMT
Set-Cookie: sysauth=72fe65ae2dd4c8e77623576faba4ac4c; path=/luci
Connection: close

{"id":null,"result":1839536,"error":null}
HTTP请求发送的JSON数据为
{"method":"uptime"}
返回内容中的result就是uptime函数的结果。

好了,到这里基本就能看出来LuCI的JSON-RPC接口是如何使用的,它的语法是这样的:

{
    "method":"函数名",
    "params":[
        "参数1",
        "参数2",
        "参数3",
        ...
    ]
}
HTTP请求的地址是:http://[ip|hostname]:[port]/luci/rpc/[库名]?auth=[auth获取的TOKEN]。本节中sys库的示例中“[库名]”字段即为“sys”

        到这里,使用LuCI的JSON-RPC接口的方法就很清楚了。那么,有哪些库是可以使用的呢?这个最好是看代码或官方文档,我这里摘抄出来,但不会更新。

sys库支持以下功能:

需要注意的是,sys库中有些子库的用法。比如luci.sys.wifi库,它的请求地址和sys是一样的。但是JSON结构中“method”的值有点差别,需要加一个"wifi."前缀(注意wifi后面有个点)。

此外,不同版本的luci支持的功能是不同的。比如luci-0.11就不支持wifi.getiwconfig,而luci-0.10支持。

update 2014.04.10:

RPC接口有时候返回的信息不是字符串,当然,也就不能以json格式展现,比如wifi.getiwinfo。这个方法从源码中看,是返回一个重载了__index的table,源码摘抄如下:

                return setmetatable({}, {
                        __index = function(t, k)
                                if k == "ifname" then
                                        return ifname
                                elseif x[k] then
                                        return x[k](ifname)
                                end
                        end
                })
这样的话,当使用rpc调用时,result的值就是空的。很悲剧啊,Luci的json-rpc接口是个半残的东东。如果想把iwinfo的内容弄出来,就需要手动修改代码了:

function gen_table(t, dev)
        local all = {}

        for k,v in pairs(t) do
                if k ~= "__index" then
                        if type(v) == "function" then
                                v = v(dev)
                        end
                        if type(v) == "table" then
                                all[k] = gen_table(v)
                        else
                                all[k] = v
                        end
                end
        end
        return all
end

function wifi.getiwinfo_rpc(ifname)
        local stat, iwinfo = pcall(require, "iwinfo")
        local t = stat and iwinfo.type(ifname)
        return gen_table(iwinfo[t], ifname)
end

function wifi.getiwinfo_item(ifname, item)
        local iwinfo = wifi.getiwinfo(ifname)
        return iwinfo[item]
end
这个是我加的wifi.getiwinfo_rpc函数用于获取所有iwinfo信息wifi.getiwinfo_item函数用于获取某个item的信息。

简单说明一下代码,wifi.getiwinfo_rpc函数开始时,调用iwinfo库(实际是iwinfo.so,iwinfo包的lua binding),这几部和原来的wifi.getiwinfo函数是一样的,返回是一个包含iwinfo所有函数的table。然后循环调用每个key对应的function,构造成一个新的table,最后返回这个新table。


FS库

请求地址:http://[ip|hostname]:[port]/luci/rpc/fs?auth=[auth获取的TOKEN]

支持功能:除支持完整的luci.fs库(http://luci.subsignal.org/api/luci/modules/luci.fs.html)外,还支持文件的读写。

readfile (filename) 读取文件,返回数据为文件内容的base64编码数据
writefile (filename, data) 写入文件,输入data为内容的base64编码

UCI库

uci库是LuCI中最重要的库,但是JSON-RPC接口只支持其中部分功能。

请求地址:http://[ip|hostname]:[port]/luci/rpc/uci?auth=[auth获取的TOKEN]

示例

添加一个section。前提添加是在/etc/config/目录下有一个router配置文件

curl -i -X POST -d '{"method":"section", "params":["router", "user", "john", {"passwd":"123456"}]}' http://192.168.1.20/luci/rpc/uci?auth=77cd0ad89ae6ead29bca594db14495f0

{"id":null,"result":true,"error":null}


获取section option value:

curl -i -X POST -d '{"method":"get", "params":["router", "john", "passwd"]}' http://192.168.1.20/cgi-bin/luci/rpc/uci?auth=77cd0ad89ae6ead29bca594db14495f0
{"id":null,"result":"123456","error":null}


支持功能:

IPKG库

ipkg库主要用于ipk包的管理,比如安装、卸载、更新等。

请求地址:http://[ip|hostname]:[port]/luci/rpc/ipkg?auth=[auth获取的TOKEN]

支持功能:Complete luci.model.ipkg library


知识共享许可协议
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。

展开阅读全文

没有更多推荐了,返回首页