Note: XML-RPC is a legacy technology that predates modern web standards. While it's largely considered outdated today, we include support and documentation for those maintaining or integrating with older systems that still rely on it.
Example:
-- Load the XML-RPC stack
local xmlrpc = require"xmlrpc"
-- Create the XML-RPC service
local xmlService = xmlrpc.new("service name", serviceDescription)
The XML-RPC stack parses the received XML into identical Lua objects. The response is handled in a similar manner, the XML-RPC stack automatically translates the response data to XML.
-- Load the XML-RPC stack
local xmlrpc = require"xmlrpc"
-- The "add" XML-RPC service
local function add(a,b)
return a + b
end
-- The "subtract" XML-RPC service
local function subtract(a,b)
return a - b
end
-- The Service Description Object used by
-- the XML-RPC constructors
local serviceDescription = {
math={
add=add,
subtract=subtract,
}
}
-- Create the XML-RPC service
local xmlService = xmlrpc.new("XML-RPC service", serviceDescription)
-- The directory callback function.
-- Service XML-RPC at relative path 'xml-rpc'
local function webservice(_ENV,path)
if path == "xml-rpc" then
xmlService:execute(request, response)
return true
else -- No other services
return false
end
end
-- Create directory: "web-service"
local serviceDir = ba.create.dir("web-service")
serviceDir:setfunc(webservice)
ba.dirtop():insert(serviceDir) -- Insert into first root directory
In this example, the math service is made available at the following URL:
XML-RPC clients: http://localhost/web-service/xml-rpc
Parameters
Return values
Throws: Throws if the interface argument is not a table, an interface table is empty, or its members are not functions.
-- A flat service exposes add directly, without an interface prefix.
local service = xmlrpc.new("Calculator", {
add = function(a, b) return a + b end
})
system.listMethods lists the callable names for either form.
An unknown interface does not fall back to a flat method with the same name.
Parameters
Return values: None. The result is sent in the HTTP response.
Each call keeps its own request and response state, so the service object can
handle overlapping requests when a method yields. The method is not called if
reading the request body fails. A no-argument call may omit the XML
params element.
Callback parameters and results: The selected method receives the decoded XML-RPC parameters as positional Lua arguments. Its first return value, result, may be a number, string, boolean, table, or a value prepared by xmlrpc.base64 or xmlrpc.iso8601. To send a fault, return nil, faultCode, faultString, where faultCode is a number and faultString is a string. Additional success return values are ignored.
Throws: Missing request or response arguments throw. Request parsing errors, unknown methods and errors raised by service methods are handled as XML-RPC faults. Errors while converting or sending the response can propagate, including unsupported callback result types.
Decoded callback values
| XML type | Lua type | Description |
|---|---|---|
| string, or value without a type element | string | Decoded text, including whitespace. Empty text becomes an empty string. |
| int, i4, double | number | Converted using Lua's tonumber. Text that cannot be converted produces a fault before the method is called. Numeric precision follows the configured Lua build. |
| boolean | boolean | Text 1 or true becomes true; other text becomes false. |
| array | table | Values in order, starting at index 1. |
| struct | table | Values indexed by member-name strings. |
| nil extension | boolean | Becomes false, preserving the position in an array or argument list. |
| base64 | string | Decoded bytes; see the helper below. |
| dateTime.iso8601 | integer or string | A timestamp when conversion succeeds; otherwise the original date text. See the conversion rules below. |
Strings and tables: Text, struct member names and fault messages are
XML-escaped. Strings preserve whitespace and decoded text; XML line-ending
normalization still applies to literal carriage returns in incoming documents.
Use xmlrpc.base64 for arbitrary binary data. Tables with only numeric
keys are encoded as arrays using their sequence from index 1, stopping at the
first hole. Other tables are structs with string member names. Repeated references
to the same table are serialized independently; a reference back to a table
currently being serialized is represented by the XML-RPC nil extension.
A numeric result (Lua number) is encoded as i4 when
it is a whole number from -2147483648 through 2147483647. Other finite numbers
are encoded as double, which may use scientific notation.
NaN and positive or negative infinity are invalid callback results and cause
response encoding to throw.
Double output uses BAS's internal number formatter. Its precision is limited
to roughly 15 significant decimal digits in the standard double build; exact
round trips are not guaranteed. For example, 1/3 is sent as
0.333333333333333. Small values such as 0.0000001
are preserved using scientific notation instead of rounding to six decimal
places.
Large Lua integers encoded as doubles are subject to floating-point precision.
Clients must accept scientific notation for double values. This is an extension to the original XML-RPC specification's decimal-only notation.
The two XML-RPC types dateTime.iso8601 and base64 requires special handling.
Parameters
Return values
Throws: Throws for unsupported argument types, fractional numeric timestamps, numbers outside the Lua integer range, or timestamps outside the supported calendar range. An omitted value uses the current time; explicit nil is not a valid value. Unconvertible date text or an out-of-range decoded timestamp with decode=true returns nil.
XML-RPC dates use ISO 8601 text. Lua timestamps count seconds from January 1, 1970 UTC; negative timestamps represent earlier dates.
Receiving:
A dateTime.iso8601 value becomes a Lua number only when the BAS
date parser accepts its text. For example, 2024-01-02T03:04:05Z
is converted to a timestamp. Conventional XML-RPC text such as
20240102T03:04:05, which has no timezone, currently remains a Lua
string. Other text the parser cannot convert also remains a string, including
dates whose timestamps do not fit the configured Lua integer type.
Sending:
You can explicitly tell the XML-RPC stack to return a UNIX time i.e. a number as dateTime.iso8601 encoding by calling xmlrpc.iso8601The following service function illustrates how to return iso8601 encoded data/time:
local function currentTimeService() return xmlrpc.iso8601(os.time()) end
Parameters
Return values
Throws: Throws if data is missing or cannot be read as a
Lua string. Encoding is deferred until the service response is generated.
B64 encoding is typically used when sending binary data. A string in Lua may contain any bytes and one can therefore store binary data in Lua strings.
Receiving:
When the XML-RPC stack receives B64 encoded data, the data is automatically converted to a Lua string.
Sending:
When the XML-RPC stack converts the response from a Lua XML-RPC service function to XML, strings are by default converted to the XML-RPC string type. The XML-RPC stack can send a Lua string as B64 encoded data, but you must explicitly tell the XML-RPC stack to do the conversion. The conversion is done by calling xmlrpc.base64
The following two service functions return response data as a XML-RPC string and as XML-RPC base64 encoded data respectively:
local function myService1()
return "This is a string"
end
local function myService2()
return xmlrpc.base64("This is a string encoded as B64")
end