Because the bulk of the work is done within the "SOAP::Lite" module itself, many of the transport-level
modules are very simple in their implementations. Transport modules are expected to define both client
and server classes within their files. If a module defines only one of the types, it is assumed that the
transport protocol itself supports only that side of the conversation. An example is
SOAP::Transport::FTP, which provides only a "SOAP::Transport::FTP::Client" class.
"SOAP::Transport::FTP" - Client class only
"SOAP::Transport::HTTP" - Client, and server classes for CGI, FCGI, Daemon and mod_perl
"SOAP::Transport::IO" - Server class only
"SOAP::Transport::JABBER" - Server and Client classes
"SOAP::Transport::LOCAL" - Client class only
"SOAP::Transport::MAILTO" - Client class only
"SOAP::Transport::MQ" - Server and Client classes
"SOAP::Transport::POP3" - Server class only
"SOAP::Transport::TCP" - Server and Client classes
METHODS
Each SOAP::Transport sub-class is expected to define (or inherit, if it is subclassing another transport
class) at least two methods. Any newly developed transport classes are also expected to adhere to this
interface. Clients are expected to implement the "new" and "send_receive" methods, and servers are
expected to implement the "new" and "handle" methods. Here they are:
new(optional key/value pairs)
$object = $class->new(%params);
Creates a new object instance and returns it. Like the constructors for both "SOAP::Lite" and
SOAP::Server classes, all arguments passed in are treated as key/value pairs, where the key is
expected to be one of the methods the class supports, and the value is the argument (or list
reference of arguments) to the method.
send_receive(key/value pairs)
$client->send_recieve(%hash_table);
(Required for client classes only) When the SOAP::Lite objects attempt to send out requests, the
means for doing so is to attempt to call this method on the object held within the SOAP::Transport
object contained within the client itself. All clients are expected to provide this, and the call to
this method always passes four values for the hash keys:
action
The URI specifying the action being performed, usually the result from the on_action hook on the
client object.
encoding
The URI of the encoding scheme that governs the message being sent.
endpoint
The URI specifying the endpoint to which the message is being sent.
envelope
The XML content of the message to be sent. It is generally the return value of the envelope
method from the SOAP::Serializer object instance that the client object maintains.
parts
Attachments to add to the request. Currently this only supports an array of MIME::Entity objects,
but in theory could support attachments of any format.
handle
$server->handle;
(Required for server classes only.) This method is the central point for the various server classes
to provide an interface to handling requests. The exact set and nature of parameters generally varies
based on the classes themselves.
SOAP::Transport::HTTP
The most commonly used transport module is the HTTP implementation. This is loaded whenever an endpoint
is given that starts with the characters, http:// or https://. This is also the most involved of the
transport modules, defining not only a client class but several different server classes as well.
HTTPPROXYSETTINGS
Because "SOAP::Client" inherits from "LWP::UserAgent", you can use any of "LWP::UserAgent"'s proxy
settings. For example:
SOAP::Lite->proxy("http://endpoint.server/",
proxy => ["http" => "http://my.proxy.server"]);
or
$soap->transport->proxy("http" => "http://my.proxy.server");
The above code samples should specify a proxy server for you. And should you use "HTTP_proxy_user" and
"HTTP_proxy_pass" for proxy authorization, "SOAP::Lite" will handle it properly.
HTTPBASICAUTHENTICATION
HTTP Basic authentication is accomplished by overriding the get_basic_credentials subroutine in
"LWP::UserAgent" (which "SOAP::Transport::HTTP::Client" is a subclass):
BEGIN {
sub SOAP::Transport::HTTP::Client::get_basic_credentials {
return 'username' => 'password';
}
}
COOKIE-BASEDAUTHENTICATION
use HTTP::Cookies;
my $cookies = HTTP::Cookies->new(ignore_discard => 1);
# you may also add 'file' if you want to keep them between sessions
my $soap = SOAP::Lite->proxy('http://localhost/');
$soap->transport->cookie_jar($cookies);
Or, alternatively, you can do the above on a single line:
$soap->proxy('http://localhost/',
cookie_jar => HTTP::Cookies->new(ignore_discard => 1));
Cookies will be taken from the response and provided to the request. You may access and manipulate
cookies received, as well as add cookies of your own by using the "HTTP::Cookies" interfaces.
SSLCERTIFICATEAUTHENTICATION
The default SSL implementation for the HTTP client library LWP::UserAgent used by SOAP::Lite is
IO::Socket::SSL.
To enable certificate based authentication, you'll have to pass your certificate and key as additional
options to the proxy() method like this:
$soap->proxy( $url, ssl_opts => {
SSL_cert_file => 'client-cert.pem',
SSL_key_file => 'client-key.pem'
});
Or you can set them later like this:
$soap->transport->ssl_opts(
SSL_cert_file => 'client-cert.pem',
SSL_key_file => 'client-key.pem'
);
If you're using Crypt::SSLeay, the following applies:
To get certificate authentication working you need to set three environment variables: "HTTPS_CERT_FILE",
"HTTPS_KEY_FILE", and optionally "HTTPS_CERT_PASS". This can be done either through the command line, or
directly within your Perl script using the $ENV variable:
$ENV{HTTPS_CERT_FILE} = 'client-cert.pem';
$ENV{HTTPS_KEY_FILE} = 'client-key.pem';
These settings are referenced by "Crypt::SSLeay". Other options (e.g. CA peer verification) can be
specified in a similar way. See Crypt::SSLeay documentation for more information.
Please note that you probably should not be using Crypt::SSLeay because it does not perform hostname
verification; LWP::UserAgent uses IO::Socket::SSL by default. See also
<https://metacpan.org/pod/Crypt::SSLeay#DO-YOU-NEED-Crypt::SSLeay>.
Those who would like to use encrypted keys may find the following thread in the SOAP::Lite newsgroup
helpful:
http://groups.yahoo.com/group/soaplite/message/729COMPRESSION
SOAP::Lite provides you with the option for enabling compression over the wire using HTTP only in both
the server and client contexts, provided that you have Compress::Zlib installed. Compression and
decompression is done transparently to your application.
A server will respond with an encoded/compressed message only if the client has asserted that it can
accept it (indicated by client sending an "Accept-Encoding" HTTP header with a 'deflate' or '*' value).
"SOAP::Lite" clients all have fallback logic implemented so that if a server doesn't understand the
specified encoding (i.e. "Content-Encoding: deflate") and returns the proper HTTP status code (415 NOT
ACCEPTABLE), the client will repeat the request without using encoding/compression. The client will then
store this server in a per-session cache, so that all subsequent requests to that server will be
transmitted without encoding.
Compression is enabled on the client side by specifying the "compress_threshold" option, and if the size
of the current request exceeds that threshold.
ClientCodeSample
print SOAP::Lite
->uri('http://localhost/My/Parameters')
->proxy('http://localhost/', options => {compress_threshold => 10000})
->echo(1 x 10000)
->result;
Servers will respond with a compressed message if the "compress_threshold" option has been specified, if
the size of the current response exceeds that threshold, and if the calling client transmitted the proper
"Accept-Encoding" HTTP Header.
ServerCodeSample
my $server = SOAP::Transport::HTTP::CGI
->dispatch_to('My::Parameters')
->options({compress_threshold => 10000})
->handle;
See also: Compress::Zlib
SOAP::Transport::HTTP::Client
Inherits from: SOAP::Client, LWP::UserAgent (from the LWP package).
With this class, clients are able to use HTTP for sending messages. This class provides just the basic
new and send_receive methods. Objects of this class understand the compress_threshold option and use it
if the server being communicated to also understands it.
CHANGING THE DEFAULT USERAGENT CLASS
By default, "SOAP::Transport::HTTP::Client" extends "LWP::UserAgent". But under some circumstances, a
user may wish to change the default UserAgent class with their in order to better handle persist
connections, or to "LWP::UserAgent::ProxyAny", for example, which has better Win32/Internet Explorer
interoperability.
One can use the code below as an example of how to change the default UserAgent class.
use SOAP::Lite;
use SOAP::Transport::HTTP;
$SOAP::Transport::HTTP::Client::USERAGENT_CLASS = "My::UserAgent";
my $client = SOAP::Lite->proxy(..)->uri(..);
my $som = $client->myMethod();
There is one caveat, however. The UserAgent class you use, MUST also be a subclass of "LWP::UserAgent".
If it is not, then "SOAP::Lite" will issue the following error: "Could not load UserAgent class
<USERAGENT CLASS>."
HTTP-KEEP-ALIVE, TIMEOUTS, AND MORE
Because "SOAP::Transport::HTTP::Client" extends "LWP::UserAgent", all methods available "LWP::UserAgent"
are also available to your SOAP Clients. For example, using "LWP::UserAgent" HTTP keep alive's are
accomplished using the following code:
my $ua = LWP::UserAgent->new(
keep_alive => 1,
timeout => 30
);
Therefore, the same initialization parameters you would pass to "LWP::UserAgent" can also be passed to
your SOAP::Lite client's "proxy" subroutine like so:
my $soap = SOAP::Lite
->uri($uri)
->proxy($proxyUrl,
timeout => 30,
keep_alive => 1,
);
This is true for all initialization parameters and methods of "LWP::UserAgent".
METHODS
http_request
This method gives you access to a prototype of the HTTP Request object that will be transmitted to a
SOAP::Server. The actual request used is a copy of that object.
Do not use this method for anything else than setting prototypic behaviour for the client object.
http_response
This method gives you access to the HTTP Response object that will be, or was transmitted to a SOAP
Server. It returns a HTTP::Response object.
SOAP::Transport::HTTP::Server
Inherits from: SOAP::Server.
This is the most basic of the HTTP server implementations. It provides the
basic methods, new and handle. The handle method's behavior is defined here,
along with other methods specific to this class. The role of this class is
primarily to act as a superclass for the other HTTP-based server classes.
handle
$server->handle;
Expects the request method to have been used to associate a HTTP::Request object with the server
object prior to being called. This method retrieves that object reference to get at the request being
handled.
request(optionalvalue)
$server->request($req_object)
Gets or sets the HTTP::Request object reference that the server will process within the handle
method.
response(optionalvalue)
$server->response(HTTP::Response->new(...));
Gets or sets the HTTP::Response object reference that the server has prepared for sending back to the
client.
make_response(code, body)
$server->make_response(200, $body_xml);
Constructs and returns an object of the HTTP::Response class, using the response code and content
provided.
make_fault(faultarguments)
$server->response($server->make_fault(@data));
Creates a HTTP::Response object reference using a predefined HTTP response code to signify that a
fault has occurred. The arguments are the same as those for the make_fault method of the SOAP::Server
class.
product_tokens
This method takes no arguments and simply returns a string identifying the elements of the server
class itself. It is similar to the product_tokens methods in the HTTP::Daemon and Apache classes.
SOAP::Transport::HTTP::CGI
Inherits from: SOAP::Transport::HTTP::Server.
This class is a direct subclass of SOAP::Transport::HTTP::Server and defines no additional methods. It
includes logic in its implementation of the handle method that deals with the request headers and
parameters specific to a CGI environment.
EXAMPLE CGI
The following code sample is a CGI based Web Service that converts celsius to fahrenheit:
#!/usr/bin/perl
use SOAP::Transport::HTTP;
SOAP::Transport::HTTP::CGI
->dispatch_to('C2FService')
->handle;
BEGIN {
package C2FService;
use vars qw(@ISA);
@ISA = qw(Exporter SOAP::Server::Parameters);
use SOAP::Lite;
sub c2f {
my $self = shift;
my $envelope = pop;
my $temp = $envelope->dataof("//c2f/temperature");
return SOAP::Data->name('convertedTemp' => (((9/5)*($temp->value)) + 32));
}
}
EXAMPLE APACHE::REGISTRY USAGE
Using a strictly CGI based Web Service has certain performance drawbacks. Running the same CGI under the
Apache::Registery system has certain performance gains.
httpd.conf
Alias /mod_perl/ "/Your/Path/To/Deployed/Modules"
<Location /mod_perl>
SetHandler perl-script
PerlHandler Apache::Registry
PerlSendHeader On
Options +ExecCGI
</Location>
soap.cgi
use SOAP::Transport::HTTP;
SOAP::Transport::HTTP::CGI
->dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method')
->handle;
WARNING:Dynamicdeploymentswith"Apache::Registry"willfailbecausethemodulewillbeonlyloadeddynamicallythefirsttime.Subsequentcallswillproduce"deniedaccess"errorsbecauseoncethemoduleisalreadyinmemory"SOAP::Lite"willbypassdynamicdeployment.Toworkaroundthis,simplyspecifyboththefullPATHandMODULEnamein"dispatch_to()"andthemodulewillbeloadeddynamically,butwillthenworkasifunderstaticdeployment.Seeexamples/server/soap.mod_cgiasanexample.SOAP::Transport::HTTP::Daemon
Inherits from: SOAP::Transport::HTTP::Server.
The SOAP::Transport::HTTP::Daemon class encapsulates a reference to an object of the HTTP::Daemon class
(from the LWP package). The class catches methods that aren't provided locally or by the superclass and
attempts to call them on the HTTP::Daemon object. Thus, all methods defined in the documentation for that
class are available to this class as well. Any that conflict with methods in
SOAP::Transport::HTTP::Server (such as product_tokens) go to the superclass. Additionally, the behavior
of the handle method is specific to this class:
handle
When invoked, this method enters into the typical accept loop in which it waits for a request on the
socket that the daemon object maintains and deals with the content of the request. When all requests
from the connection returned by the accept method of the HTTP::Daemon object have been processed,
this method returns.
REUSING SOCKETS ON RESTART
Often when implementing an HTTP daemon, sockets will get tied up when you try to restart the daemon
server. This prevents the server from restarting. Often users will see an error like "Cannot start
server: port already in use." To circumvent this, instruct SOAP::Lite to reuse open sockets using "Reuse
=> 1":
my $daemon = SOAP::Transport::HTTP::Daemon
-> new (LocalPort => 80000, Reuse => 1)
EXAMPLE DAEMON SERVER
use SOAP::Transport::HTTP;
# change LocalPort to 81 if you want to test it with soapmark.pl
my $daemon = SOAP::Transport::HTTP::Daemon
-> new (LocalAddr => 'localhost', LocalPort => 80)
# specify list of objects-by-reference here
-> objects_by_reference(qw(My::PersistentIterator My::SessionIterator My::Chat))
# specify path to My/Examples.pm here
-> dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method')
;
print "Contact to SOAP server at ", $daemon->url, "\n";
$daemon->handle;
SOAP::Transport::HTTP::Apache
Inherits from: SOAP::Transport::HTTP::Server.
This class provides an integration of the SOAP::Server base class with the mod_perl extension for Apache.
To work as a location handler, the package provides a method called handler, for which handle is made an
alias. The new method isn't functionally different from the superclass. Here are the other methods
provided by this class:
handler(Apacherequest)
$server->handler($r)
Defines the basis for a location handler in the mod_perl fashion. The method expects an Apache
request object as the parameter, from which it pulls the body of the request and calls the superclass
handle method.
Note that in this class, the local method named handle is aliased to this method.
configure(Apacherequest)
$server->configure(Apache->request);
Per-location configuration information can be provided to the server object using the Apache
DirConfig directive and calling this method on the object itself. When invoked, the method reads the
directory configuration information from Apache and looks for lines of the form:
method => param
Each line that matches the pattern is regarded as a potential method to call on the server object,
with the remaining token taken as the parameter to the method. Methods that take hash references as
arguments may be specified as:
method => key => param, key => param
The key/value pairs will be made into a hash reference on demand. If the server object doesn't
recognize the named method as valid, it ignores the line.
EXAMPLE APACHE MOD_PERL SERVER
See examples/server/Apache.pm and Apache::SOAP for more information.
httpd.conf
<Location /soap>
SetHandler perl-script
PerlHandler SOAP::Apache
PerlSetVar options "compress_threshold => 10000"
</Location>
SOAP::Apache.pm
package SOAP::Apache;
use SOAP::Transport::HTTP;
my $server = SOAP::Transport::HTTP::Apache
->dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method');
sub handler { $server->handler(@_) }
1;
See also Apache::SOAP.
SOAP::Transport::HTTP::FCGI
Inherits from: SOAP::Transport::HTTP::CGI.
This is an extension of the SOAP::Transport::HTTP::CGI that implements the differences needed for the
FastCGI protocol. None of the methods are functionally different.
SOAP::Transport::IO
The SOAP::Transport::IO-based class allows for a sort of I/O proxying by allowing the application to
configure what files or filehandles are used. This module supplies only a server class.
SOAP::Transport::IO::Server
Inherits from: SOAP::Server.
The server class defined here inherits all methods from SOAP::Server, and adds two additional methods
specific to the nature of the class:
in
$server->in(IO::File->new($file));
Gets or sets the current filehandle being used as the input source.
out
$server->out(\*STDERR);
Gets or sets the filehandle being used as the output destination.
SOAP::Transport::LOCAL
The SOAP::Transport::LOCAL module is designed to provide a no-transport client class for tracing and
debugging communications traffic. It links SOAP::Client and SOAP::Server so that the same object that
"sends" the request also "receives" it.
SOAP::Transport::LOCAL::Client
Inherits from: SOAP::Client, SOAP::Server. The implementations of the new and send_receive methods
aren't noticeably different in their interface. Their behavior warrants description, however:
new When the constructor creates a new object of this class, it sets up a few things beyond the usual
SOAP::Client layout. The is_success method is set to a default value of 1. The dispatch_to method
inherited from SOAP::Server is called with the current value of the global array @INC, allowing the
client to call any methods that can be found in the current valid search path. And as with most of
the constructors in this module, the optional key/value pairs are treated as method names and
parameters.
send_receive
The implementation of this method simply passes the envelope portion of the input data to the handle
method of SOAP::Server. While no network traffic results (directly) from this, it allows for debug
signals to be sent through the SOAP::Trace facility.
SOAP::Transport::MAILTO
This transport class manages SMTP-based sending of messages from a client perspective. It doesn't provide
a server class. The class gets selected when a client object passes a URI to proxy or endpoint that
starts with the characters, mailto:.
SOAP::Transport::MAILTO::Client
Inherits from: SOAP::Client.
The client class for this protocol doesn't define any new methods. The constructor functions in the same
style as the others class constructors. The functionality of the send_receive method is slightly
different from other classes, however.
When invoked, the send_receive method uses the MIME::Lite package to encapsulate and transmit the
message. Because mail messages are one-way communications (the reply being a separate process), there is
no response message to be returned by the method. Instead, all the status-related attributes (code,
message, status, is_success) are set, and no value is explicitly returned.
SOAP::Transport::POP3
POP3 support is limited to a server implementation. Just as the MAILTO class detailed earlier operates by
sending requests without expecting to process a response, the server described here accepts request
messages and dispatches them without regard for sending a response other than that which POP3 defines for
successful delivery of a message.
SOAP::Transport::POP3::Server
Inherits from: SOAP::Server.
The new method of this class creates an object of the Net::POP3 class to use internally for polling a
specified POP3 server for incoming messages. When an object of this class is created, it expects an
endpoint to be specified with a URI that begins with the characters pop:// and includes user ID and
password information as well as the hostname itself.
The handle method takes the messages present in the remote mailbox and passes them (one at a time) to the
superclass handle method. Each message is deleted after being routed. All messages in the POP3 mailbox
are presumed to be SOAP messages.
Methods for the Net::POP3 object are detected and properly routed, allowing operations such as
$server->ping( ).
This means that the endpoint string doesn't need to provide the user ID and password because the login
method from the POP3 API may be used directly.