ToC | DocOverview | CGDoc | RelNotes | FAQ | Index | PermutedIndex
| Allegro CL version 9.0 Unrevised from 8.2 to 9.0. 8.2 version

# An XML-RPC API for Allegro Common Lisp

This document contains the following sections:

1.0 XML-RPC in Allegro CL introduction
2.0 Various utility objects in XML-RPC
3.0 XML-RPC client api
4.0 XML-RPC data api
5.0 XML-RPC server api
6.0 XML-RPC examples
7.0 Index

## 1.0 XML-RPC in Allegro CL introduction

The xml-rpc module implements classes and functions to support the XML-RPC protocol for remote function calls through HTTP connections. The protocol is described in detail on the XML-RPC Home Page at http://xmlrpc.com/. The XML-RPC Home Page also lists public XML-RPC servers and many community links.

The version described in this document is (2 9 5) -- see `*xml-rpc-version*` for a discussion of version numbers.

All symbols in this module are exported from the `net.xml-rpc` package. The module is named `xml-rpc`. It requires the AllegroServe (`aserve`) and the XML Utilities (`xmlutils`) modules. You load the `xml-rpc` module with a form like:

    (require :xml-rpc)

This implementation of XML-RPC is separate and independent from the Lisp RPC implememtation in the `aclrpc` module (see rpc.htm). The Lisp RPC module is more appropriate for closely coupled applications on one processor or on a local area network. XML-RPC is more appropriate for occasional contact between applications separated by large distances and by firewalls.

The key features (both positive and negative) of the XML-RPC protocol are as follows. First the positive features:

- It is a published protocol implemented in a variety of languages and operating systems.
- It allows communication between applications implemented in different languages.
- It allows communication with established public servers.
- A Lisp application can be setup as a public server.
- It allows communication over the internet and through firewalls.

Now the negative features:

- It is not intended for time-critical communications, or for the transmission of large volumes of data.
- It is an asymmetrical protocol allowing calls from the client to the server but not callbacks from the server to the client. (It is however possible for an application to implement both client and server functions in one program to allow some two-way communication.)

## 2.0 Various utility objects in XML-RPC

The following variables, conditions, and methods are useful when using XML-RPC.

### *xml-rpc-version*

### Variable

#### Package: net.xml-rpc

A list of three integers that describe the XML-RPC version. The version described in this document is (2 9 5).

### xml-rpc-version

### Function

#### Package: net.xml-rpc

Arguments: &optional stream

If stream is `nil`, return a string with a formatted version message.

If stream is a stream, write the formatted version message to the stream.

If stream is the keyword `:number`, return an integer of the form `aabbcc` where `aa`, `bb`, and `cc` are the version number components.

Otherwise, return the value of `*xml-rpc-version*`, a list of three version numbers.

### *xml-rpc-time-zone*

### Variable

#### Package: net.xml-rpc

When `nil`, convert time values in local time zone. This was the behavior in previous version of the XML-RPC module.

The default value is 0 to specify UTC time values.

### *xml-rpc-base64*

### Variable

#### Package: net.xml-rpc

The default value is `:string` to implement behavior compatible with previous versions.

A value `:array` specifies that base64 values are decoded into USB8 arrays. A Lisp value to be encoded as <base64> must be specified as a USB8 array.

### xml-rpc-condition

### Class

#### Package: net.xml-rpc

The superclass of conditions associated with xml-rpc.

### xml-rpc-fault

### Class

#### Package: net.xml-rpc

A condition associated with xml-rpc.

Instances are created with `:fault-code` and `:fault-string` initargs.

If a user-defined server method signals this condition during its execution, the result sent to the client is a fault message where the faultCode element is taken from the :fault-code initarg and the faultString element is taken from the :fault-string initarg.

### xml-rpc-error

### Class

#### Package: net.xml-rpc

A condition associated with xml-rpc.

### xml-rpc-response-error

### Class

#### Package: net.xml-rpc

A condition associated with xml-rpc.

### xml-rpc-argument-error

### Class

#### Package: net.xml-rpc

A condition associated with xml-rpc.

### xml-rpc-fault-code

### Generic Function

#### Package: net.xml-rpc

Arguments: xml-rpc-fault

Accesses the code slot of an `xml-rpc-fault`.

### xml-rpc-fault-string

### Generic Function

#### Package: net.xml-rpc

Arguments: xml-rpc-fault

Accesses the string slot of an `xml-rpc-fault`.

### xml-rpc-error-place

### Generic Function

#### Package: net.xml-rpc

Arguments: xml-rpc-error

Accesses the place slot of an `xml-rpc-error`.

### xml-rpc-error-data

### Generic Function

#### Package: net.xml-rpc

Arguments: xml-rpc-error

Accesses the data slot of an `xml-rpc-error`.

## 3.0 XML-RPC client api

The Client API allows a Lisp application to call any XML-RPC server.

In a client call:

1. Lisp arguments are converted and encoded to satisfy the requirements of the protocol,
2. The remote method is called by sending the encoded message to the server.
3. The result of the call is received from the server, decoded and mapped to a Lisp value.

### encode-xml-rpc-call

### Function

#### Package: net.xml-rpc

Arguments: name &rest args

The purpose of this function is to encode a client call into a string ready to be transmitted to a server.

The name argument is a symbol or string that names a method available at the server.

The remaining arguments are Lisp values that are encoded into suitable protocol items. Default encoding rules are defined for many Lisp data types. Some arguments must be explicitly encoded by calling make-xml-rpc-encoding described later.

If the same call needs to be made several times, there is some efficiency gained in encoding the call once, and reusing the string.

The XML-RPC protocol requires that each http request includes a length and that the length is accurate.

### call-xml-rpc-server

### Function

#### Package: net.xml-rpc

Arguments: server name &rest args

The purpose of this function is to call the remote method and to decode the result.

The first argument is a list of keyword value pairs describing the desired XML-RPC server.

The second argument is the name of a remote method and the remaining arguments are arguments passed to the remote methods.

The value returned by the function is the decoded value returned by the remote method.

If the call results in an XML-RPC Fault, then a Lisp error of type `xml-rpc-fault` is signaled.

The keyword arguments that may appear in the server list are `:url`, `:agent`, and `:host`.

The url argument specifies the URL of the remote server. The default value is taken from the variable `*xml-rpc-url*`.

The agent argument may be a string that is passed to the server as the :user-agent header element. The default value is `:aserve`; this value sends the AllegroServe version string.

The host argument may be a string that is passed to the server as the `:host` header element. When this argument is `nil`, the `:host` header element is omitted.

### xml-rpc-call

### Function

#### Package: net.xml-rpc

Arguments: encoded &key url agent host headers

The purpose of this function is to call the remote method and to decode the result.

The first argument is a string produced by the encode-xml-rpc-call function. It is the encoded version of the method name and argument values.

The value returned by the function is the decoded value returned by the remote method.

If the call results in an XML-RPC Fault, then a Lisp error of type `xml-rpc-fault` is signalled.

The url argument specifies the URL of the remote server. The default value is taken from the variable `*xml-rpc-url*`.

The agent argument may be a string that is passed to the server as the :user-agent header element. The default value is `:aserve`; this value sends the AllegroServe version string.

The host argument may be a string that is passed to the server as the `:host` header element. When this argument is `nil`, the `:host` header element is omitted.

The headers argument is combined with the host header element and passed on to AllegroServe.

Any other arguments are passed on to the AllegroServe do-http-request function. Since the xml-rpc-call function passes its own version of the method, protocol, content-type, content, and user-agent arguments, these should not be specified.

### *xml-rpc-url*

### Variable

#### Package: net.xml-rpc

The value of this variable is the default URL used to make a client call. If many calls to the same server are made in some context, the setting of this variable may be used to provide the correct default URL.

## 4.0 XML-RPC data api

We provide classes and functions that give the programmer control over the encoding and decoding of Lisp values.

Lisp Data Type | Default Encoding | Default Decoding
integer | <int> or <i4> | integer
float | <double> | float
string | <string> | string
list | <array> | list
xml-rpc-struct | <struct> | xml-rpc-struct
xml-rpc-structany nil or non-nil | None. <boolean> encoding must be specified explicitly as `:boolean`. | t or nil
any data coerced to a string or USB8 array depending on the setting of `*xml-rpc-base64*` | None. <base64> encoding must be specified explicitly as `:base64`. | string or USB8 array depending on setting of the variable `*xml-rpc-base64*`.

Some XML-RPC data types must be explicitly created by the application since it is not possible to infer them from the Lisp data type.

### xml-rpc-struct

### Class

#### Package: net.xml-rpc

The purpose of this class is to represent the XML-RPC <struct> data type.

### xml-rpc-struct-members

### Generic Function

#### Package: net.xml-rpc

Arguments: xml-rpc-struct

The default method returns a list of members defined in the <struct>. Each item in the list is an instance of the `xml-rpc-member` class.

### xml-rpc-member

### Class

#### Package: net.xml-rpc

The purpose of this class is to represent the members defined in a <struct>.

### xml-rpc-member-name

### Generic Function

#### Package: net.xml-rpc

Arguments: xml-rpc-member

The deafult method returns a string that represents the name of the <struct> member.

### xml-rpc-member-value

### Generic Function

#### Package: net.xml-rpc

Arguments: xml-rpc-member

The default method returns the Lisp value of the <struct> member.

### xml-rpc-encoding

### Class

#### Package: net.xml-rpc

The purpose of this class is to represent an explicit encoding of a Lisp value into an XML-RPC protocol value. Instances of this class are created when a default encoding cannot be used to create the desired encoding.

### xml-rpc-slot-value

### Generic Function

#### Package: net.xml-rpc

Arguments: xml-rpc-struct slot-name &key (error-p t)

The purpose of this function is to access the value of a member in a <struct> instance.

The slot-name argument can be a string or a symbol. If specified as a string it must match the member name exactly. If specified as a symbol, the symbol name must match. In a Modern image, matches are determined with equal; in an ANSI image, with string-equal, for a more sloppy but convenient match. (See case.htm for a discussion of case modes and Modern and ANSI images.)

If the error-p argument is `nil`, return `nil` if the member is not found.

The value returned is the current Lisp value of the member.

The setf of this generic function is called as follows:

    ((setf xml-rpc-slot-value) new-value xml-rpc-struct slot-name &key (error-p t))

It may be used to store a new value as the Lisp value of the member.

### make-xml-rpc-struct

### Function

#### Package: net.xml-rpc

Arguments: &rest name-value-sequence

This function creates an object from which an XML-RPC <struct> instance can be encoded. The arguments are an alternating sequence of name and value arguments. The name argument names a member of the <struct>, the value argument is a Lisp value to be encoded as the value component of the member.

Each name argument may be a string or symbol or a list. A name or symbol specifies the name of the member and a default encoding for the Lisp value. A list consists of a name for the member and a keyword that specifies the desired XML-RPC encoding. All the encoding keywords are described with the encode-xml-rpc-value function. A third element in the list may be `t` or `nil` to specify whether the encoding for the Lisp value should be cached in the member object.

### make-xml-rpc-encoding

### Function

#### Package: net.xml-rpc

Arguments: data &optional type &rest more

The purpose of this function is to make an explicit encoding of a Lisp value to create an encoded value that cannot be obtained from a default encoding.

If the type argument is omitted or `nil`, then the data argument value is encoded by default rules:

Lisp Data Type | Default Encoding
integer | <i4>
float | <double>
string | <string>
sequence | <array>
xml-rpc-encoding | the encoding stored in the object
xml-rpc-struct | <struct>

The type argument may be a keyword to ensure a specific encoding:

- `:int`: The data argument is truncated to an integer. Encoded value is <i4>.
- `:truncate`: The data argument is truncated to an integer. Encoded value is <i4>.
- `:round`: The data argument is rounded to an integer. Encoded value is <i4>.
- `:string`: The data argument is converted to a string with a ~A format directive. Encoded value is <string>.
- `:double`: The data argument is coerced to a double-float. Encoded value is <double>.
- :boolean: The data argument may be nil(false) or non-`nil` (true). Encoded value is <boolean>.
- `:date`: The data argument may be an integer treated as a CL universal time number or a list of (second minute hour day month year). In the second form, the year is treated literally - not as in the CL definition, to allow dates before 1900. Encoded value is <dateTime.iso8601>.
- `:base64`: The encoding is always a string of base64 characters. Encoded value is <base64>. The expected data and the conversion depends on the value of `*xml-rpc-base64*`:
  - `:string` - this default value implements the behavior in previous versions. If the data is not a string, it is converted to a string with the ~A format directive. The string is then encoded as base64 characters.
  - `:array` - this value implements new behavior in version (2 9 6). The data must be of type `(array (unsigned-byte 8)` (*)). The bytes in the array are encoded as base64 characters.
- :struct: If the data argument is an `xml-rpc-struct` instance, then the data argument is encoded as in the default case.

  Otherwise, the data argument is ignored and the more argument must be a list of items of the form (name value [type] ...) where name denotes a member name, value is the Lisp value of the member and the remainder of the list is used in a recursive call to encode the Lisp value.

  This second form allows a <struct> argument to be encoded without creating an xml-rpc-struct instance.

  Encoded value is a <struct>.

- :encoded: The data argument must be a string that contains a correct XML-RPC value encoding.

If an encoded value cannot be created, a Lisp error of type `xml-rpc-argument-error` is signaled.

### encode-xml-rpc-value

### Function

#### Package: net.xml-rpc

Arguments: data &optional type &rest more

This function is very similar to make-xml-rpc-encoding, but the value returned is a string that contains an XML-RPC value encoding. Since the resulting string must be stored in an xml-rpc-encoding instance to be recognized in an argument conversion, this function is only useful in some circumstances where creating the xml-rpc-encoding instance must be delayed. An instance is created with the form

    (make-xml-rpc-encoding (encode-xml-rpc-value ...) :encoded)

## 5.0 XML-RPC server api

The server API allows a Lisp application to act as an XML-RPC server on the internet. Other applications, possibly written in other languages such as Java and Perl, may then call the methods exported by the server.

### xml-rpc-server

### Class

#### Package: net.xml-rpc

### xml-rpc-export

### Class

#### Package: net.xml-rpc

### xml-rpc-server-name

### Generic Function

#### Package: net.xml-rpc

Arguments: xml-rpc-server

The default method accesses the name of an `xml-rpc-server`.

### *xml-rpc-server*

### Variable

#### Package: net.xml-rpc

### make-xml-rpc-server

### Function

#### Package: net.xml-rpc

Arguments: &key start enable publish class name introspect

Programming note: The XMLRPC module uses AllegroServe as the web interface. The start and enable arguments are provided as convenient ways of interacting with AllegroServe in typical situations. In some situations, such as when two web servers may be running in the same Lisp image, the AllegroServe documentation (aserve/aserve.html) should be consulted to make sure that AllegroServe and XMLRPC interact correctly. It is also typically undesirable to call aserve:start twice for the same server instance.

This function creates an instance of the `xml-rpc-server` class to hold the definitions of a set of exported functions.

The publish argument defines how the server is seen from the client side. It is the list of arguments passed to the aserve:publish function. If the `:path` argument is missing, the value "/RPC2" is supplied. If `:function` or `:content-type` are specified, an error is signaled.

If the start argument is non-`nil`, then the function aserve:start is called. If the start argument is a list, this list is used as the argument list to aserve:start, otherwise aserve:start is called with all default arguments.

If the enable argument is non-`nil`, then the server is enabled. If the enable argument is non-`nil`, but the start argument is `nil`, then AllegroServe must already be running when make-xml-rpc-server is called.

The name argument is returned to clients as the :server header entry. The default name is "AllegroServe/x.x.x(Allegro Common Lisp)".

The class argument can specify the name of a sub-class of `xml-rpc-server`. If the class is specified as a list, the car is the class name, the cdr is a list of initargs to make-instance. Note that the initargs `:parameters publish :name name` are always included. This feature allows applications to add slots or methods to the server object. This object is bound to `*xml-rpc-server*` when an exported function is called.

If the introspect argument is non-`nil`, the standard introspection methods are exported automatically (see export-standard-xml-rpc-methods).

### enable-xml-rpc-server

### Generic Function

#### Package: net.xml-rpc

Arguments: server &optional enable-exports

This function enables a server and optionally enables any exported methods.

A method is available to a client only if all three conditions are met:

- AllegroServe is running
- the XML-RPC server is enabled
- the particular method is enabled

If many methods need to be exported, the normal sequence of events is to make a disabled server, define and enable all the methods, and finally enable the server. In this way all the methods become available simultaneously.

### disable-xml-rpc-server

### Generic Function

#### Package: net.xml-rpc

Arguments: server

This function disables the server and makes all the methods unavailable.

### export-xml-rpc-method

### Generic Function

#### Package: net.xml-rpc

Arguments: server name-spec result-spec &rest arg-specs

This function makes a method available to XML-RPC client applications.

The server argument must be an `xml-rpc-server` instance.

The name-spec argument may be a symbol or a list. When name-spec is a list, the first element must be a string or symbol that names the exported method - this is the name that a client uses to call the remote method. The second element of the list is the name of the Lisp function that will be called as the exported method. If the second element in the list is omitted or `nil`, then the first element must be a symbol that is also the name of the Lisp function to be called. The third element in the list is `nil` or non-`nil`; non-`nil` specifies that the method is enabled immediately; if `nil` is specified, then the method must be enabled explicitly by calling enable-xml-rpc-method; if the third element is omitted, `t` is assumed and the method is enabled. The fourth element in the list may be a string containing a description of the method. When name-spec is a symbol, it is equivalent to `(symbol nil t)`.

The result-spec argument must be one of the keywords that represent XML-RPC data types. It is the type of the result returned to the caller. The available keywords are `:int`, `:double`, `:string`, `:boolean`, `:array`, `:struct`, and `:base64`.

The remaining arguments are a list of XML-RPC data type keywords that describe the method signature.

Several methods, with different argument signatures, may be exported under the same method name.

The Lisp function is called with the decoded arguments of the remote call. The value returned by the Lisp function is encoded using the data type of the value and the result-spec. If the function returns an instance of the class `xml-rpc-encoding` then the result-spec is ignored and the encoding stored in the instance is used. If the function signals a condition of type `xml-rpc-fault`, then the fault message is returned to the remote caller.

### xml-rpc-method-help

### Generic Function

#### Package: net.xml-rpc

Arguments: server name

This function returns the help string associated with an exported method name. All the methods with one name share the same help string.

The setf of this generic function is called as follows:

    ((setf xml-rpc-method-help) new-string server name)

It may be used to store a new help string.

### export-standard-xml-rpc-methods

### Generic Function

#### Package: net.xml-rpc

Arguments: server &optional enable

This function exports three introspection methods frequently provided by XML-RPC servers. The enable argument may be `nil` to suppress automatic enabling of these methods.

The methods are:

- system.listMethods(), returns <array>.
- system.methodSignature(<string>), returns <array>.
- system.methodHelp((<string>), returns <string>.

### enable-xml-rpc-method

### Generic Function

#### Package: net.xml-rpc

Arguments: server name &rest arg-specs

This function enables an individual exported method, or all the methods with the same name.

If the arg-specs argument is a list of the single keyword `:all`, then all the methods with the specified name are enabled.

Otherwise, arg-specs must be a list of keywords that represent XML-RPC data types. The method with the matching argument signature is enabled.

### disable-xml-rpc-method

### Generic Function

#### Package: net.xml-rpc

Arguments: server name &rest arg-specs

This function disables an individual exported method, or all the methods with the same name.

If the arg-specs argument is a list of the single keyword `:all`, then all the methods with the specified name are disabled.

Otherwise, arg-specs must be a list of keywords that represent XML-RPC data types. The method with the matching argument signature is disabled.

## 6.0 XML-RPC examples

A simple client call:

    (xml-rpc-call
      (encode-xml-rpc-call "currentTime.getCurrentTime")
      :url "http://time.xmlrpc.com:80/RPC2"
      )

A client call with an argument:

    (xml-rpc-call
      (encode-xml-rpc-call "system.methodSignature" "meerkat.getCategories")
      :url "http://www.oreillynet.com/meerkat/xml-rpc/server.php"
      )

The validation server:

    (defun make-validator1-server (&optional (port 8080))
      (let ((s (make-xml-rpc-server
    	      :start nil :enable t
    	      :publish '(:path "/ACL-XML-RPC2"))))

          (export-xml-rpc-method s
    	 '("validator1.arrayOfStructsTest" validator1-array-of-struct)
    	 :int :array)

          (export-xml-rpc-method s
    	 '("validator1.countTheEntities" validator1-count)
    	 :struct :string)

          ...

          (start :port port)
          (enable-xml-rpc-server s)
          s))

and one of the validator functions:

    (defun validator1-count (string)
       ;; validator1.countTheEntities   -- returns :struct
       ;;
       ;; This handler takes a single parameter, a string,
       ;;  that contains any number of predefined entities,
       ;;  namely <, >, &, ' and ".
       ;; Your handler must return a struct that contains five fields,
       ;;  all numbers: ctLeftAngleBrackets,  ctRightAngleBrackets,
       ;;               ctAmpersands, ctApostrophes, ctQuotes.

      (make-xml-rpc-struct
           "ctLeftAngleBrackets"  (count #\< string)
           "ctRightAngleBrackets" (count #\> string)
           "ctAmpersands"         (count #\& string)
           "ctApostrophes"        (count #\' string)
           "ctQuotes"             (count #\" string)))

## 7.0 Index

- call-xml-rpc-server
- disable-xml-rpc-method
- disable-xml-rpc-server
- enable-xml-rpc-method
- enable-xml-rpc-server
- encode-xml-rpc-call
- encode-xml-rpc-value
- export-standard-xml-rpc-methods
- export-xml-rpc-method
- make-xml-rpc-encoding
- make-xml-rpc-server
- make-xml-rpc-struct
- `xml-rpc-argument-error`
- xml-rpc-call
- `xml-rpc-condition`
- `xml-rpc-encoding`
- xml-rpc-error-data
- xml-rpc-error-place
- `xml-rpc-error`
- `xml-rpc-export`
- xml-rpc-fault-code
- xml-rpc-fault-string
- `xml-rpc-fault`
- xml-rpc-member-name
- xml-rpc-member-value
- `xml-rpc-member`
- xml-rpc-method-help
- `xml-rpc-response-error`
- xml-rpc-server-name
- `xml-rpc-server`
- `*xml-rpc-server*`
- xml-rpc-slot-value
- xml-rpc-struct-members
- `xml-rpc-struct`
- `*xml-rpc-url*`
- xml-rpc-version
- `*xml-rpc-version*`

Copyright (c) 1998-2019, Franz Inc. Oakland, CA., USA. All rights reserved.
This page was not revised from the 8.2 page.
Created 2012.5.30.

ToC | DocOverview | CGDoc | RelNotes | FAQ | Index | PermutedIndex
| Allegro CL version 9.0 Unrevised from 8.2 to 9.0. 8.2 version