XML-RPC Library

_XML-RPC_ Library

By Matt Jadud and Noel Welsh
An Untyped Production

Time-stamp: <06/01/04 15:34:39 nhw>

Keywords: _xml_, _xmlrpc_, _xml-rpc_

Current version: 1.4
Requires PLT Version: 359.100 or greater.


This library implements the XML-RPC protocol as specified at

XML-RPC is a popular protocol for interface to Internet
services such as blog engines.

Basic Types

> struct (exn:xmlrpc exn) : ()

A subtype of exn, this exception is raised whenever the
XML-RPC library encounters an error.

> struct (exn:xmlrpc exn) : code
A subtype of exn:xmlrpc, this exception is raised when the
XML-RPC server responds to the client with a fault.  The
code is an integer containing the fault code returned by the
server.  The fault message returned by the server is
contained in the exception message (which is a field in the
exn type).

Client-side Functions

To use the library, require 

> xmlrpc-server : string integer string -> (string -> (any ... -> any))
> xmlrpc-server : url -> (string -> (any ... -> any))

Returns a function configured to make XML-RPC requests to
the given URL.  The function accepts a string, the name of
the method, and returns a function of any arguments which
calls the method with the given arguments.


This example calls the examples.getStateName method on the

  > (define betty (xmlrpc-server "" 80 "RPC2"))
  > (define get-state-name (betty "examples.getStateName"))
  > (get-state-name 42)

PLT Servlet Functions

To use the Untyped XML-RPC library to build a servlet, 
include one of the two servlet-based libraries. If you want
to write a unit-based servlet, include "". 
If you want to write a module-based servlet, use 
"". For PLT Scheme version 352.5 and later,
we recommend using the module-based approach.

> add-handler : symbol (any ... -> any) -> void

An XML-RPC servlet defines one or more endpoints that 
can be invoked by a remote client. The simple act of 
defining a Scheme function does not automatically
provide it to the outside world; this would be fundamentally
unsafe. Each function to be exposed externally must be
mappend onto a name by which it can be called.

For example:

(define (add x y) (+ x y))
(add-handler 'math.add add)

These two lines of code define a Scheme function ('add') 
and provide it to an outside client under the name
'math.add'. The same function can be provided under
multiple names:

(define (add x y) (+ x y))
(add-handler 'math.add add)
(add-handler 'addFun add)

'case-lambda', 'match-lambda', and functions of 
variable argument can be bound in the same way.

> handle-xmlrpc-requests : syntax

The last form you must have in an XML-RPC servlet
is the 'handle-xmlrpc-requests' form. This expands
into a signed unit that takes each incoming request
and handles it as an XML-RPC request.

A complete unit-based XML-RPC handler for adding
two numbers would look like:

(require (planet "" 
                 ("schematics" "xmlrpc.plt" 1 3)))

(define (add x y) (+ x y))

(add-handler 'math.add add)


A module-based servlet (PLT Scheme 352.5 and later)
would look like

(module add mzscheme
  (require (planet "" 
                   ("schematics" "xmlrpc.plt" 1 3)))
  (provide interface-version manager timeout start)
  (define (add x y) (+ x y))
  (add-handler 'math.add add)

The 'provide' statement provides a start, timeout, and 
continuation manager to the webserver for your
XML-RPC servlet. These are defined in the Untyped
XML-RPC module-based servlet library.

PLT CGI Functions
The XML-RPC library can also be used for implementing 
CGI-based endpoints under a server like Apache. These
endpoints are significantly slower at this time, as 
each XML-RPC call requires Apache to launch an entire
MzScheme instance to handle the call. Servlet handlers
are roughly two orders of magnitude faster.

Typically, CGIs are executed as a user other than the 
author of the CGI (eg. 'nobody' or 'www'). This
presents a problem, as the PLaneT request to include
the XML-RPC library will likely fail, causing your 
CGI to fail as well.

There are many solutions to this problem. One is to 
execute the CGIs in a SuExec'd environment. Or, you could
ask your systems administrator to install the PLaneT 
package for the XML-RPC library in a globally accessible
location. Below, we've demonstrated how you might 
make the library work for you in an environment where this
is not an option.

#!/path/to/mzscheme -gqr

(require (lib "" "planet"))
(PLANET-DIR "/path/to/writable/planet-dir")
(CACHE-DIR "/path/to/writable/planet-cache")
(LINKAGE-FILE "/path/to/writeable/planet-linkage")

(require (planet "" 
                 ("schematics" "xmlrpc.plt" 1 3)))

(add-handler 'add (lambda (a b) (+ a b)))



First, we require the configuration library for PLaneT.
We then define PLaneT-writable directories for all of its
files: these will need to be locations writable by 
the webserver (eg. owned/writable by 'nobody', 'www',
or whatever user your webserver runs as). Then, include
the XML-RPC library, and from there, add your handlers.

Before you handle your XML-RPC requests, you will need
to output HTTP headers. This may change in the future;
Apache CGI support is new, and currently a moving target.

As of this release, the server-side of the XML-RPC
library has not been thoroughly tested. This means we 
have not written a test suite in a variety of other 
languages to test against our server.

The following clients are suspected to work against
the Untyped XML-RPC server running as either a 
servlet or Apache CGI process:

* The Untyped XML-RPC client (Scheme)
* The Python native XML-RPC client (Python)
* Ecto, a popular blogging package for OSX (Cocoa)
* Apache XML-RPC v2 (Java)

These tests, however, were not exhaustive. Your milage
may vary. Please report any difficulties or patches to
jadudm at gmail dot com.

If you are writing unit-based servlets using a version 
of PLT Scheme prior to 352.5, it would appear that there
is a continuation leak. Although the XML-RPC library 
does not use contuations, it seems like they are created
and not freed regardless.

For authors writing servlet-based XML-RPC handlers,
we recommend writing against the module-based library, and
using PLT Scheme version 352.5 or later, as these issues
were resolved by that point.