Contents
- Introduction to TclSOAP
- SOAP Package Commands
- CGI Server Package
- TclHTTPD SOAP Server Utilities
- TclHTTPD XML-RPC Server Utilities
- Download Information
- TclDOM Packages for TclSOAP
-
TclSOAP over SSL
I have been testing out using SOAP from Tcl and have come up with
the following package to provide Tcl commands for SOAP remote
procedure calls. The following code demonstrates the ease of use for
simple RPC calls. This is a work in progress and some parts need
more work. In particular the transport layer needs to be able to be
configured to cope with proxy HTTP servers and authenticating proxys
and the like. Still it may be usefull as-is.
This example connects the Tcl procedure getTemp to the
remote method hosted by XMethods.
In all these examples Tcl commands are prefixed with the %
character that is my prompt under tclsh. Results are printed without
the preceeding prompt character.
% package require SOAP
1.6
% SOAP::create getTemp \
-uri "urn:xmethods-Temperature" \
-proxy "http://services.xmethods.net/soap/servlet/rpcrouter" \
-params { "zipcode" "string" }
::getTemp
% getTemp 90810
41.2
We bring in the package and then define the method. The
configuration requires a URI for the XML namespace of the SOAP
method and a URL for the service. The
params configure option
allows the Tcl procedure to do simple parameter checking without
passing duff packets over the network.
Another example, this time using the extremely clever
SOAP::Lite
Perl package as a server, a Celcius to Fahrenheit convertor. We
shall test it using that peculiar temperature -40. This time I
want the Tcl procedure to be called C2F.
% package require SOAP
1.6
% SOAP::create C2F \
-uri "http://www.soaplite.com/Temperatures" \
-proxy "http://services.soaplite.com/temper.cgi" \
-params { "temp" "float"}\
-name c2f
::C2F
% C2F -40.0
-40
%
It will be possible to use different transport protocols to
transfer the SOAP packets. At this time only HTTP is
supported. You may need to configure the transport subsystem so
the SOAP::configure command has a -transport
option. For example, at work I live behind a Microsoft NT
firewalling proxy web server. So I need to tell the SOAP transport
about the proxy. This is an authenticating proxy, so I have to add
a header to all HTTP requests using the Proxy-Authorization HTTP
field. Here's how I set up my system and then create a command for
the SOAP::Lite languages method.
% package require SOAP
1.6
% SOAP::configure -transport http -proxy proxyhost:8080 \
-headers { "Proxy-Authorization" "Basic dXNlcm5hbWUgOiBwYXNzd29yZA==" }
% SOAP::create languages \
-uri "http://www.soaplite.com/Demo" \
-proxy "http://services.soaplite.com/hibye.cgi" \
-params {}
::languages
% languages
Perl sh C
%
To setup a method to use a different transport there is a
-transport option for the method configure command. This
should be set to the name of a procedure that will be called with
the URL of the SOAP service and the XML data of the SOAP
request. It should return the reply packet or error. For example,
I have a dummy transport procedure that prints the SOAP request
and doesn't send it anywhere. To see what is being generated for a
method:
# A dummy SOAP transport procedure to examine the SOAP requests generated.
proc SOAP::Transport::print::print {procVarName url soap} {
puts "$soap"
}
% SOAP::configure languages -transport SOAP::Transport::print::print
::languages
% languages
<?xml version='1.0'?>
<SOAP-ENV:Envelope
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<ns:languages xmlns:ns="http://www.soaplite.com/Demo" />
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
%
For debugging purposes it can be useful to see the XML that was
generated for the SOAP method request at each end. The
SOAP::dump command will return the XML for the last
transaction using HTTP for a named method.
Using Complex Variable Types
The SOAP protocol specifies a number of variable types in the
default encoding style. Most of these are simply mapped into Tcl
however the Array and Struct types create a special problem for
Tcl users. Given a string such as "The cat sat on the
mat" there is no way in Tcl to determine if this is a string
of 6 words, a list with 6 elements or the list representation of a
three element array. In SOAP terms, these would be a string, an
array of strings, or a struct. To properly implement SOAP clients we must
provide a method by which the SOAP framework can determine what
the parameters should be mapped into. This is achieved by the
-params configuration option and the rpcvar package.
The -params option is used the specify both the number of
parameters, their names and their types. In SOAP, the names of the
parameters is supposed to be more important than their
positions. So:
SOAP::create a -params {num double} |
Parameter num is a double |
SOAP::create a -params {num dateTime} |
Parameter num is a SOAP dateTime date. |
SOAP::create a -params {nums int()} |
nums is an array of integers |
SOAP::create a -params {dates dateTime()} |
dates is an array of SOAP dateTime values |
SOAP::create a -params {anArray array} |
anArray is an array of mixed types. |
The final version in an untyped array. This can also be specified
as
ur-type() or
any(). In the SOAP 1.1
specification these arrays are set to
ur-type[n]
Structs can be handled in a similar fashion. The simplest case
of a structure of simple guessable types can be handled by
specifying a type of struct. In this case the parameter
is expected to be a list of name-value pairs. For more complex
types, particularly structs containing structs we need to define a
new type. This is done using the typedef procedure from
the rpcvar package.
package require rpcvar
namespace import -force rpcvar::typedef
typedef {
intValue int
floatValue float
stringValue string
} simpleStruct
SOAP::create a -params {myStruct simpleStruct}
a {intValue 2 stringValue "Hello, World!" floatValue 2.5}
An example using a nested struct type can be found in the
samples/soapinterop.tcl
file shipped with TclSOAP.
- SOAP::create methodName ?option value ...?
Create a Tcl binding for a remote procedure call using
SOAP. See configure for the permitted options.
- SOAP::configure -transport protocol ?option value ...?
Used for global configuration of the available
transports. The options passed in to this command are dependent on
the transport mchanism. The only transports currently available
The HTTP transport may require a proxy server and possible
other headers to be included. This is where to add this
information. For example, to pass an authenticating proxy server I
need to provide the name of the server and a Proxy-Authorize HTTP
header using the Trf package to provide the base64 encoding
procedure.
SOAP::configure -transport http -proxy wwwproxy:8080 \
-headers { "Proxy-Authorize" "Basic [base64 -enc user:pass]" }
- SOAP::configure methodName ?option value ...?
- -uri URI
- The URI for the XML namespace in which this
method has been defined.
- -proxy URL
- Specify the URL of the server providing the
implementation of this method.
- -params list
- Configure the parameters required for this
method. list should be a list of pairs consisting of the
parameter name and the parameter type. The Tcl procedure will
check the number of parameters when constructing the SOAP
request. e.g.:
SOAP::configure getTemp -params { "zipcode" "string" }
SOAP::configure c2f -params { "temperature" "float" }
SOAP::configure hi -params {}
- -transport protocolProc
- Select the transport protocol used for this
method. protocolProc should be a Tcl command procedure that
takes the URL of the SOAP server and the SOAP XML data to be
sent. This procedure will send the request and receive the
answer.
- -name methodName
- By default a Tcl command is
created in the current namespace with the same name as the SOAP
method. If the Tcl procedure is created with a different name then
the -name configuration option must be used to set the SOAP
method name explicitly.
- -action SOAPActionValue
- The SOAP 1.1 specification requires SOAP POST requests to
have an HTTP SOAPAction header. This may have an empty value if
not required (which is the default) or it may be required to be
set to a specific value to pass though firewalls.
- -wrapProc procedureName
- Set the procedure used to wrap up the method parameters for
transport to the server. This procedure takes the SOAP
methodName followed by all the parameters required for the
method call and returns the generated XML data for the RPC
call. By default for SOAP requests this is set to
SOAP::soap_request and for XML-RPC methods to
SOAP::xmlrpc_request. This option is only likely to be
used if you are implementing a new RPC protocol.
- -replyProc procedureName
- A hook procedure can be defined to be called once the
response packet has been received but before the XML is
parsed. Provided the server returned an HTTP 200 response then
this procedure is guarunteed to be called even if the reply
contains an error response. The procedure is called with two
parameters, the first being the SOAP method name and the second
being the XML text of the reply. The hook procedure should
return the new XML text suitable for processing by the
-parseProc procedure. For example:
proc my_reply_hook { methodName xml } {
puts "$xml"
return $xml
}
- -parseProc procedureName
- Specify the procedure used to parse the XML of the reply
and to extract the result value. The default depends upon the
setting of the -xmlrpc configuration option and is either
SOAP::parse_soap_response or
SOAP::parse_xmlrpc_response. The procedure takes two
parameters as for the -replyProc option but should return the
result value from the XML packet.
- -postProc procedureName
- An optional hook procedure may be specified here that will
be called once the result value has been obtained from the XML
packet. This procedure will take two parameters, the first is
the SOAP method name and the second the result value extracted
from the XML. The procedure should return the new result value.
By default no procedure is defined.
- -command callback
- Provide support for asynchronous methods. This option
causes the SOAP method invocation to return immediately and the
callback procedure is called once the round trip finally
completes. The procedure will be called with an additional
argument that is the data returned by the remote method. The
callback procedure must exist before the SOAP method is
configured as the procedure name is namespace qualified during
configuration.
proc gotInfo {window data} { ... }
SOAP::configure getInfo -command {gotInfo .frame1.edit} ...
- SOAP::cget methodName option
Retrieve a configuration value from the method. The
optionName should be one of those listed for
configure. There is one additional read-only value to be
obtained:
- http
- retrieve the handle for the last HTTP
request. This is only set if the transport in use is HTTP. You can
examine the HTTP data using procedures from the http package. i.e.:
puts "[::http::data [SOAP::cget getTemp http]]"
or
set r [::http::code [SOAP::cget getTemp http]]
- SOAP::dump option methodName
Returns information about the last HTTP transaction.
- -reply
- returns the XML text of the servers reply
- -request
- returns the XML text that was sent to the server
- -meta
- returns the HTTP protocol meta information
- SOAP::invoke methodName methodParameters
Make a SOAP call to the configured server. This is not
expected to be called by a user but is called by the Tcl command
procedure for this SOAP method.
- SOAP::proxyconfig
This command presents a dialog box used to configure the
SOAP package to work with a proxy server. The fields are used to
call SOAP::configure -transport http with the relevant
options. The first entry field takes the name and port of the
proxy server (eg: webproxy:8080) and the second two fields are
used to configure a Basic Authentication HTTP header to allow
operation with an authenticating proxy. (such as a Windows NT
IIS server).
The package can be downloaded from
the SourceForge project site
.
This file should be unpacked somewhere handy and you should set
your TCLLIBPATH environment variable to suit. For windows users,
you may as well unpack it to X:\Program Files\Tcl\lib\
You can also obtain the source via
anonymous CVS or
browse the CVS repository. You might also find recent news and
update information on the
TclSOAP project page. This is also the place to report bugs,
submit patches and discuss any issues.
If you would like to make a donation to support development of
this software, you may do so via PayPal. This is not required and in
no way affects the free licensing of this software.