SourceForge Logo

TclSOAP CGI Server Package

Introduction

The SOAP::CGI package allows you to provide SOAP web services from Tcl scripts via the CGI script capabilities of your web server. This document describes the use of this package with the Apache httpd server but the package should be applicable to any other server supporting the Common Gateway Interface.

The package provides a fairly comprehensive framework to deal with hiding the details of the web service protocols. The Tcl scripts implementing the service need to know nothing of XML nor the RPC protocol in use. Errors are returned via the normal Tcl error mechanism. The only special feature needed is variable type hinting. It is not possible to distinguish between a string with whitespace and a list in Tcl, so the rpcvar package is used to provide the additional type information when required.

Installation

Installation really only requires placing a script into the http servers cgi-bin directory and writing some service implementations. A generic script is provided as cgi-bin/rpc with some example services in cgi-bin/soap/. The package has four variables to configure so that it can find the service implementations:

package require SOAP::CGI
set SOAP::CGI::soapdir "../method-scripts"
set SOAP::CGI::soapmapfile "soapmap.dat"
set SOAP::CGI::xmlrpcdir "../method-scripts"
set SOAP::CGI::xmlrpcmapfile "xmlrpcmap.dat"
set SOAP::CGI::logfile "../logs/rpc.log"
SOAP::CGI::main

The SOAP and XML-RPC implementations can be the same, as above, or placed into separate directories. The log file is optional (unset the variable to disable logs) and will need to be writable by the httpd user - this usually means it needs to be world writable. The soapmap file is used to identify the implementation script file from the SOAPAction header. There is more information in the sample soapmap.dat file.

The script needs to be able to execute using tcl 8.3 or better and needs to be able to find the TclSOAP package. Bear in mind that the httpd process will not run with your environment (unless you are working on Windows). The supplied script shows how you can set the location of the package, should you need to. If you are using the Windows Apache server then you can't set the environment before execing tclsh so you need to manipulate the auto_path variable from within the CGI script instead.

Writing Service Implementations

Upon receipt of an HTTP POST the CGI framework examines the data and decides which RPC protocol should handle the request. The handlers then retrieve the method name from the request and look for a file with this name in the configured directory. This is sourced and then evaluated with the arguments obtained from the POST data. For example, the implementation for the square service will be the file ../method-scripts/square with the following code:

proc square {num} {
    return [expr $num * $num]
}

Given the configuration shown above, this implementation will be used for both SOAP and XML-RPC requests to the square service. It is necessary to identify the commands that are webservices to prevent clients from running arbitrary Tcl commands. This is done by the use of the SOAP::export or the corresponding XMLRPC::export commands. This means that the actual implementation for the square webservice would be:

package require SOAP
package require XMLRPC

SOAP::export square
XMLRPC export square

proc square {num} {
    return [expr $num * $num]
}

For more complex types such as structs, the reply will need to be an rpcvar so that the RPC handler can package the result correctly. So the implementation of the platform service which returns a struct containing the ::tcl_platform variable information is as follows

package require rpcvar
package require SOAP
SOAP::export platform

proc platform {} {
    return [rpcvar::rpcvar struct ::tcl_platform]
}

Structs are passed to the implementing procedure as a list of name value pairs suitable for use with array set ..., arrays are passed in as Tcl lists and everything else is passed in as a string. If the result type cannot be guessed then you should return a typed variable otherwise it will be assumed to be a string. The only types that can be guessed are integer, double and boolean (if expressed with true or false).

Providing Type Information

rpcvar to be done

Further Information

Look in the cgi-bin/soap subdirectory in the TclSOAP distribution for some examples of service implementations. There is an implementation of the UserLand SOAP interoperability suite that is used to ensure the package conforms to this standard. These illustrate the use of arrays and structs fairly comprehensively.

The client code for the validator suite is in samples/validator.tcl. To test a server implementation, source this script and run validate_soap url. This will run the test suite against the server implementation at the provided URL.

A similar client implementation of the XMethods Interoperability Lab test suite is in soapinterop.tcl. To use, source this file and execute soapinterop::validate url.