LuaXMLRPC Reference Manual |
XML-RPC interface to the Lua programming language |
LuaXMLRPC is a Lua library to build XML-RPC clients and servers. It enables a Lua program to:
LuaXMLRPC provides a simple API and an abstraction layer over XML avoiding manipulation of string representation of data structures.
LuaXMLRPC is based on LuaExpat and on Lua 5.0.
The abstraction layer over HTTP depends on LuaSocket 2.0.
XML-RPC elements are usually represented by the simplest correspondent Lua object. When the correspondance is not obvious, a Lua table is used with a field specifying the element.
When converting from XML-RPC element to a Lua object, a table
with a field tag
is used. The child elements are
stored at numbered indexes and white space is ignored.
XML-RPC data type | Lua object |
double int i4 |
number |
string | string |
boolean | boolean |
struct arrray |
table |
other elements |
{ tag = "element name", [1] = <first child>, [2] = <second child>, [3] = ..., } |
A conversion from a Lua object to an XML-RPC can be made automatically or explicitly. The automatic conversion rules are:
Lua object | XML-RPC data type |
number | int or double |
string | string |
boolean | boolean |
{ key = val } |
<struct> <member> <name>key</name> <value>val</value> </member> </struct>val is converted according to the same rules. |
"1"
instead of 1
). The library tries to
convert integral numbers to integer types, otherwise converting
them to floating point numbers.
The file xmlrpc.lua
implements all basic support
for encoding and decoding XML-RPC messages and for transforming
data types between the two representations. Following is the list
of functions.
clEncode (method_name, params*) =>
method_call
methodCall
element. It receives a string with the method's name and an
optional list of parameters. The result is a string containing the
XML-RPC document. clDecode (method_response) => ok,
results
methodResponse
element. The result is a boolean
indicating wether the call was successful or not followed by the
resulting objects (typically a methodResponse has only one value so
only one Lua object will be returned). In case of error the
false
value is followed by the XMLRPC
faultString and the faultCode. This values are
extracted from the fault
element. srvDecode (method_call) => method_name,
list_params
methodCall
element.
The result is a string with the name of the method to be called and
a Lua table with the arguments to the call. srvEncode (object, is_fault) =>
method_response
methodResponse
element. It receives a Lua object (a number, a string, a table, a
"created typed value" etc.) with the return value of the call. The
result is a string containing the XML-RPC document. Note that
XML-RPC defines that a response only returns one value so a
Lua function that returns more than one value has to pack
them into a table to guarantee that all of them will be returned.
The second parameter (is_fault
) can be used to force a
fault
element to be generated instead of a
params
. In this case, the Lua object must be a table
with the members faultCode
and
faultString
.
srvMethods (tab_or_func)
dispatch (method_name) => function
The file xmlrpc.http.lua
implements a simple
stand-alone client based on LuaSocket 2.0. The
following function is provided:
call (url, method, params*)
method
at location
url
with the given params
(if any). The
method
and params
parameters will be just
passed to clEncode function. The result is
the same as clDecode function: a boolean
indicating whether the call was successful or not, followed by the
response value (if successful) or by the faultString and the
faultCode (if the call fails).
The distribution also offers a simple XML-RPC server implemented over a CGI launcher. This launcher just have to offer a way to decode POST data and to send data back to the client.
The file xmlrpc.cgi.lua
implements a simple XML-RPC
server using the package post
that can parse incoming
POST data from the http server. An appropriate environment for
writing Lua functions is implemented; a new assert
function generates a XML-RPC fault in case of a false condition; a
respond
function creates the correct header for the
responses.
The main goal of this file is to give a starting point for other real implementations.
require "xmlrpc.http" local ok, res = xmlrpc.http.call ("http://www.oreillynet.com/meerkat/xml-rpc/server.php", "system.listMethods") print (ok) for i, v in pairs(res) do print ('\t', i, v) end
The tablerequire "xmlrpc" double_array_type = xmlrpc.newArray ("double") double_array = xmlrpc.newTypedValue ( { 1.1, 2, 3, 4 }, double_array_type) double_array_array_type = xmlrpc.newArray (double_array_type) double_array_array = xmlrpc.newTypedValue ( { { 11, 12, 13, }, { 21, 22, 23, }, { 31, 32, 33, }, }, double_array_array_type)
double_array_array
will be:
<array> <data> <value> <array> <data> <value><double>11</double></value> <value><double>12</double></value> <value><double>13</double></value> </data> </array> </value> <value> <array> <data> <value><double>21</double></value> <value><double>22</double></value> <value><double>23</double></value> </data> </array> </value> <value> <array> <data> <value><double>31</double></value> <value><double>32</double></value> <value><double>33</double></value> </data> </array> </value> </data> </array>
Note that the packagerequire "xmlrpc.cgi" local kepler_home = "http://www.keplerproject.org" local kepler_products = { "luasql", "lualdap", "luaexpat", "luaxmlrpc", } local kepler_sites = { luasql = kepler_home.."/luasql", lualdap = kepler_home.."/lualdap", luaexpat = kepler_home.."/luaexpat", luaxmlrpc = kepler_home.."/luaxmlrpc", } -- Register methods xmlrpc.srvMethods { kepler = { products = function (self) return kepler_products end, site = function (self, prod) return kepler_sites[prod] end, } } -- Parse POST data local doc = {} post.parsedata (doc) -- Decode method call local method, arg_table = xmlrpc.srvDecode (doc[1]) local func = xmlrpc.dispatch (method) local ok, result, err = pcall (func, unpack (arg_table or {})) if ok then result = { code = 3, message = result, } end respond (xmlrpc.srvEncode (result, not ok)
post
and the function
respond
should be provided by the cgi launcher.