This is Info file pm.info, produced by Makeinfo version 1.68 from the input file bigpm.texi.  File: pm.info, Node: SOAP/OutputStream, Next: SOAP/Packager, Prev: SOAP/Lite, Up: Module List Writes SOAP fragments ********************* NAME ==== SOAP::OutputStream - Writes SOAP fragments SYNOPSIS ======== # note that we need SOAP::Envelope to bootstrap use SOAP::Envelope; sub output_fcn { my $string = shift; print $string; } my $namespaces_to_preload = ["urn:foo", "urn:bar"]; my $env = SOAP::Envelope->new(\&output_fcn, $namespaces_to_preload); my $body = $env->body(); # here is where we actually use SOAP::OutputStream my $child = $body->compound_accessor("urn:quux", "reverse_string", undef, undef, 0); $child->simple_accessor(undef, "s", undef, undef, "dlrow olleH"); $child->term(); $body->term(); $env->term(); This creates the following XML: dlrow olleH DESCRIPTION =========== SOAP::OutputStream encapsulates the details of writing SOAP packets into a few easy to use functions. In order to bootstrap a SOAP stream (and get your first SOAP::OutputStream reference), you'll need to use SOAP::Envelope, as shown in the example above. The simple_accessor function ---------------------------- This function writes a simple accessor (e.g., a string or number, as opposed to a compound type). It takes two sets of URI/typenames, one for the accessor and one for the optional xsi:type attribute. At a minimum, you must specify the accessor_name and content. The compound_accessor function ------------------------------ This function opens a new compound accessor (by writing an open XML tag), and returns a new SOAP::OutputStream that you should use to write the contents of that accessor. This function always creates nested elements. If you want to create an independent element, call reference_accessor instead. The is_package parameter allows you to open a new package at this node; the OutputStream will write all further independent elements at this level in the XML document, creating a standalone XML fragment within the SOAP envelope. The OutputStream will complain if all references within the package cannot be resolved when this node is closed. See the SOAP spec for details on packages. NOTE NOTE NOTE: The SOAP "package" attribute was dropped when the SOAP spec went from version 1.0 to version 1.1. Use package-related functionality at your own risk - you may not interoperate with other servers if you rely on it. I'll eventually remove this feature if it doesn't reappear in the spec soon. The reference_accessor function ------------------------------- This function creates a reference (SOAP:href) node, and stores the specified object until the current package is closed, at which time a serializer is obtained for the object (based on its type) and is asked to serialize itself to a new stream at the level of the package. Note that if you're not using packages explicitly, then the system will perform this resolution and serialization when you switch from creating Headers to creating the Body, and once again when the Body is terminated. The object referenced is guaranteed to only be serialized once (assuming you've obeyed the SOAP rules for packages and Header/Body object reference sharing). The term function ----------------- Call this function when you want to close the node you're working with. This does several things - it seals the package if the node you're using was created as a package, and it writes an end tag (along with doing some other internal bookeeping that's pretty important). Don't forget to call this function before opening a new sibling node. DEPENDENCIES ============ SOAP::Defs AUTHOR ====== Keith Brown SEE ALSO ======== SOAP::Envelope  File: pm.info, Node: SOAP/Packager, Next: SOAP/Parser, Prev: SOAP/OutputStream, Up: Module List SOAP internal helper class ************************** NAME ==== SOAP::Packager - SOAP internal helper class SYNOPSIS ======== use SOAP::Packager; my $packager = SOAP::Packager->new('s:', 1, sub { print shift } ); # some object used as a reference my $object = SOAP::Object->new(); # on a given packager, register() always returns the same id for a given object my $id = $packager->register($env, $object); unless($id == $packager->register($env, $object)) { die "internal error" } # this serializes objectA $packager->seal($envelope); # note that the package is still valid unless($id == $packager->register($env, $object)) { die "internal error" } my $objectB = SOAP::Object->new(); my $idB = $packager->register($env, $objectB); unless($idB == $packager->register($env, $objectB)) { die "internal error" } # this just serializes objectB - objectA was already serialized before $packager->seal($env); # this does nothing except waste some cycles enumerating a hash table $packager->seal($env=); # hash tables shut down at destruction of packager, releasing object references $packager = undef; DESCRIPTION =========== This is an internal class used by the SOAP/Perl implementation. It is designed to manage a table of object references and XML ids used for serializing object graphs that may contain multiref data (and perhaps even cycles). If you are extending SOAP/Perl, the above synopsis will probably be all you need if you want to reuse this class. Whatever you pass for the $env reference should implement a function called _alloc_id that returns a unique string each time it is called. This is normally implemented by SOAP::Envelope, so you can see a sample implementation there. NOTE NOTE NOTE: The SOAP "package" attribute was dropped when the SOAP spec went from version 1.0 to version 1.1. Use package-related functionality at your own risk - you may not interoperate with other servers if you rely on it. I'll eventually remove this feature if it doesn't reappear in the spec soon. AUTHOR ====== Keith Brown SEE ALSO ======== SOAP::Envelope SOAP::OutputStream  File: pm.info, Node: SOAP/Parser, Next: SOAP/Serializer, Prev: SOAP/Packager, Up: Module List Parses SOAP documents ********************* NAME ==== SOAP::Parser - Parses SOAP documents SYNOPSIS ======== use SOAP::Parser; my $parser = SOAP::Parser->new(); $parser->parsefile('soap.xml'); my $headers = $parser->get_headers(); my $body = $parser->get_body(); DESCRIPTION =========== SOAP::Parser has all the logic for traversing a SOAP packet, including Envelope, Header, and Body, dealing with namespaces and tracking down references. It is basically an extension of a SAX-like parser, which means that it exposes an event-driven interface that you can implement to get the results of the parse. By default, SOAP/Perl provides SOAP::GenericInputStream to handle these events, which simply produces an object graph of hash references. If you want something different, on a per type URI basis, you can register alternate handlers so you can produce different output. See SOAP::TypeMapper for details. The handler needs to implement a set of methods, and these are outlined in SOAP::GenericInputStream along with descriptions of what the default behavior is (in other words, what SOAP::GenericInputStream does for each of these methods). The benefit of this design is that it avoids using a DOM to parse SOAP packets; rather, the packet is unmarshaled directly into whatever final form you need. This is more efficient in space and time than first unmarshaling into a DOM and then traversing the DOM to create an object graph that is meaningful to your program. To get the full benefit of this, you may need to implement a handler that creates your custom object graph from the SOAP packet (see SOAP::GenericInputStream for details). Since SOAP::Parser does all the hard work, implementing a handler (or set of handlers) is really pretty painless. new(TypeMapper) --------------- Creates a new parser. Be sure *not* to reuse a parser for multiple SOAP packets - create one, use it, and then throw it away and get a new one if you need to parse a second SOAP packet. TypeMapper is an optional parameter that points to an instance of SOAP::TypeMapper that allows you to register alternate serializers and deserializers for different classes of objects. See the docs for that class for more details. If you don't pass this parameter, the system uses a default TypeMapper object. parsestring(String) ------------------- Parses the given string. parsefile(Filename) ------------------- Parses the given file. get_headers() ------------- After parsing, this function returns the array of headers in the SOAP envelope. Specifically, this function returns an array reference that contains zero or more hash references, each of which always take the following form: { soap_typeuri => 'namespace qualification of header', soap_typename => 'unqualified name of header', content =>
} For instance, the following header: 42 would be deserialized in this form: { soap_typeuri => 'urn:foo', soap_typename => 'MyHeader', content => 42, } while this header: something something else would be deserialized (by default) in this form: { soap_typeuri => 'urn:foo', soap_typename => 'MyHeader', content => { soap_typeuri => 'urn:foo', soap_typename => 'MyHeader', m1 => 'something', m2 => 'something else', }, } Note the redundancy of the soap_typeuri and soap_typename isn't strictly necessary in this case because this information is embedded in the content itself. However, because of the potential (and common need) for sending scalars as the entirety of the header content, we need some way of communicating the namespace and typename of the header. Thus the content, for consistency, is always packaged in a hash along with explicit type information. get_body() ---------- After parsing, this function retrieves the body of the SOAP envelope. Since it doesn't make sense to send just a scalar as the body of a SOAP request, we don't need the redundancy of packaging the content inside of a hash along with its type and namespace (as was done above with headers). For instance: something something else would be deserialized (by default) as the following: { soap_typeuri => 'urn:foo', soap_typename => 'MyBody', m1 => 'something', m2 => 'something else', } DEPENDENCIES ============ XML::Parser::Expat SOAP::GenericInputStream SOAP::Defs AUTHOR ====== Keith Brown SEE ALSO ======== SOAP::GenericInputStream  File: pm.info, Node: SOAP/Serializer, Next: SOAP/SimpleTypeWrapper, Prev: SOAP/Parser, Up: Module List serialization utilities *********************** NAME ==== SOAP::Serializer - serialization utilities SYNOPSIS ======== Used internally by SOAP/Perl DESCRIPTION =========== Used internally by SOAP/Perl AUTHOR ====== Keith Brown  File: pm.info, Node: SOAP/SimpleTypeWrapper, Next: SOAP/Struct, Prev: SOAP/Serializer, Up: Module List deprecated ********** NAME ==== SOAP::SimpleTypeWrapper - deprecated SYNOPSIS ======== deprecated DESCRIPTION =========== Introduced in SOAP/Perl 0.24 Deprecated in SOAP/Perl 0.25 AUTHOR ====== Keith Brown  File: pm.info, Node: SOAP/Struct, Next: SOAP/StructSerializer, Prev: SOAP/SimpleTypeWrapper, Up: Module List support for ordered hashes ************************** NAME ==== SOAP::Struct - support for ordered hashes SYNOPSIS ======== use SOAP::EnvelopeMaker; # produce a body that will retain the order of params # when serialized to a SOAP envelope my $body = SOAP::Struct->new( a => 3, b => 4, ); # same as above, but explicit xsi:type attrs will also # be included for accessor 'b' my $body = SOAP::Struct->new_typed( a => 3, undef, b => 4, 'float', ); DESCRIPTION =========== The SOAP spec explicitly mandates that it should be possible to serialize structures and control both the names of the accessors and the order that they appear in the serialized stream. (SOAP 1.1, section 7.1, bullet 3) Prior to SOAP/Perl 0.25, this was impossible, as the only way to serialize a "struct" was to use a hash, which is unordered in Perl. This class allows you to specify a structure where the order of the accessors is preserved. This is important when making SOAP calls to many traditional RPC-style servers that expect parameters to arrive in a certain order (and could generally care less about the names of those parameters). new(accessor_1_name => accessor_1_value, ...) --------------------------------------------- This constructor feels the same as constructing a hash, but the order of the accessors will be maintained when this "super-hash" is serialized. new_typed(accessor_1_name => accessor_1_value, accessor_1_type, ...) -------------------------------------------------------------------- This constructor is for convenience - if you pass something other than undef for accessor_n_type, then accessor_n_value will be wrapped with a TypedPrimitive class with the specified type. This way you can force explicit type names to be used for each element in the structure. See SOAP::TypedPrimitive for a discussion of why this can be important. DEPENDENCIES ============ SOAP::TypedPrimitive AUTHOR ====== Keith Brown SEE ALSO ======== SOAP::TypedPrimitive  File: pm.info, Node: SOAP/StructSerializer, Next: SOAP/Test, Prev: SOAP/Struct, Up: Module List (internal) serializer for SOAP structs ************************************** NAME ==== SOAP::StructSerializer - (internal) serializer for SOAP structs DEPENDENCIES ============ SOAP::Struct SOAP::Serializer AUTHOR ====== Keith Brown SEE ALSO ======== SOAP::Struct  File: pm.info, Node: SOAP/Test, Next: SOAP/Transport/ACTIVEWORKS, Prev: SOAP/StructSerializer, Up: Module List Test framework for SOAP::Lite ***************************** NAME ==== SOAP::Test - Test framework for SOAP::Lite SYNOPSIS ======== use SOAP::Test; SOAP::Test::Server::run_for('http://localhost/cgi-bin/soap.cgi'); DESCRIPTION =========== SOAP::Test provides simple framework for testing server implementations. Specify your address (endpoint) and run provided tests against your server. See t/1*.t for examples. COPYRIGHT ========= Copyright (C) 2000-2001 Paul Kulchenko. All rights reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. AUTHOR ====== Paul Kulchenko (paulclinger@yahoo.com)  File: pm.info, Node: SOAP/Transport/ACTIVEWORKS, Next: SOAP/Transport/ActiveWorks/AutoInvoke/Client, Prev: SOAP/Test, Up: Module List Server/Client side ActiveWorks support for SOAP::Lite for Perl ************************************************************** NAME ==== SOAP::Transport::ACTIVEWORKS - Server/Client side ActiveWorks support for SOAP::Lite for Perl SYNOPSIS ======== use SOAP::Lite +autodispatch => uri => 'activeworks://myBroker:clientGroup@my.active.host:7449', proxy => 'http://my.http.host/aw-soap/', on_fault => sub { my($soap, $res) = @_; die ref $res ? $res->faultdetail : $soap->transport->status, "\n"; } ; print "Remote Time is ", ${ AdapterDevKit::timeRequest->SOAP::publish }{time}, "\n"; DESCRIPTION =========== The SOAP::Transport::ACTIVEWORKS class provides support for ActiveWorks URIs to access ActiveWorks brokers through an HTTP proxy server with SOAP structured requests. The package also allows an ActiveWorks adapter to be used as a SOAP server to either invoke arbitrary Perl classes or to publish and return ActiveWorks events specified in a SOAP structure. This class mirrors the interface of the SOAP::Transport::HTML class which should be referred to for general documentation. The URI differences will be discussed here with example usage. ACTIVEWORKS URI COMPONENTS -------------------------- The general schema of an ActiveWorks URI is as follows: activeworks://:@: All parameters are optional and defaults can be set within the BEGIN section of the SOAP::Transport::ActiveWorks package. The assumed client group is always 'SOAP' and SOAP requests are forwarded to a SOAP adapter (*server/soap_adapter.pl* is provided) assumed to be running on the default broker. If an alternative client group is specified the SOAP request is assumed to contain fields corresponding to a named ActiveWorks event available on the broker. See section `PSEUDO EVENTS' for details. HTTP PROXY SETTINGS ------------------- When using an HTTP server to proxy publish AW events the 'proxy' autodispatcher parameter should be set to your SOAP server URI as you would with a normal SOAP request. use SOAP::Lite +autodispatch => uri => 'urn:', # use default broker, client group, etc. proxy => 'http://my.http.host/aw-soap/', on_fault => sub { my($soap, $res) = @_; die ref $res ? $res->faultdetail : $soap->transport->status, "\n"; } ; Note that the SOAP server, 'aw-soap' in this case, must be enabled to dispatch requests to an ActiveWorks handler. The provided Apache::AwSOAP module demonstrates this: package Apache::AwSOAP; use strict; use Apache; use SOAP::Transport::ACTIVEWORKS; my $server = SOAP::Transport::ACTIVEWORKS::Apache -> dispatch_to( '' ); sub handler { $server->handler(@_); } 1; The *client/http-aw-soap-aw-calculator.pl* script demonstrates relaying a SOAP envelope from an http server to an ActiveWorks adapter for processing. To work with your normal soap server, the AwGateway module may be used to relay an ordinary SOAP request as an ActiveWorks event to a broker specified in the autodispatcher 'uri' parameter. See section AwGateway. USING AN ACTIVEWORKS BROKER AS A SOAP SERVER -------------------------------------------- The ACTIVEWORKS module along with the *soap-lite-adapter.pl* allows you to use an ActiveWorks broker as a SOAP server. Like a normal http server the SOAP adapter will instantiate and invoke the class and method specified in a SOAP request. In addition, classes may be mapped onto ActiveWorks events (see section PSEUDO CLASSES), mapped onto an adapter subroutine for special handling (see *http-callback-aw-aw-time.pl* for a demonstration) and even relayed to an http SOAP server specified in the method URI (see *aw-soap-aw-http-calculator.pl* for example usage). The *soap-lite-adapter.pl* allows an ActiveWorks client to send and receive requests to a broker with a SOAP envelope to take advantage of the SOAP protocol in a purely ActiveWorks environment. PSEUDO CLASSES -------------- ActiveWorks events may be instantiated and published much like remote classes. With a 'pseudo class' we treat the remote event as if it were just another SOAP class that we want to access remotely. The difference will be that we can only send a hash reference as an argument and always get a hash type in return (which is in keeping with the Aw package treatment of events as hashes). Also we publish the event with the dummy method '->publish'. use SOAP::Lite +autodispatch => uri => 'activeworks://myBroker:clientGroup@my.active.host:7449', proxy => 'http://my.http.host/aw-soap/', on_fault => sub { my($soap, $res) = @_; die ref $res ? $res->faultdetail : $soap->transport->status, "\n"; } ; # # Hash are used to transport ActiveWorks request event data: # my %request = (); # # Populate the event fields: # $request{numbers} = \@Numbers; # # Reset default publish timeout from 20 seconds: # $request{_event_timeout} = 40000; # # Publish event and force returned SOAPStruct type into a hash: # my %results = %{ AdapterDevKit::calcRequest->SOAP::publish ( \%request ) }; The client script *http-pseudo-aw-aw-calculator.pl* and *http-pseudo-aw-aw-time.pl* demonstrate pseudo class usage. AwGateway --------- The AwGateway module is a normal SOAP module that you would keep in your "Deployed Modules" directory. With AwGateway you access an ActiveWorks broker through your usual SOAP server and bi-pass the ACTIVEWORKS module altogether. See the AwGateway full documentation and the accompanying client script *http-gateway-aw-aw-calculator.pl* demonstration use. DEPENDENCIES ============ The Aw package for Perl interfaces to ActiveWorks libraries. The SOAP-Lite package. SEE ALSO ======== See SOAP::Transport::HTTP COPYRIGHT ========= Copyright (C) 2000 Paul Kulchenko. All rights reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. AUTHOR ====== The SOAP::Transport::ACTIVEWORKS module was developed by Daniel Yacob and is derived directly from SOAP::Transport::HTTP by Paul Kulchenko. Daniel Yacob, L Paul Kulchenko, L  File: pm.info, Node: SOAP/Transport/ActiveWorks/AutoInvoke/Client, Next: SOAP/Transport/ActiveWorks/AutoInvoke/Server, Prev: SOAP/Transport/ACTIVEWORKS, Up: Module List Automarshall methods for Perl SOAP ********************************** NAME ==== SOAP::Transport::ActiveWorks::AutoInvoke::Client - Automarshall methods for Perl SOAP SYNOPSIS ======== #!/usr/bin/perl -w # # Client example that goes with server example # in SOAP::Transport::ActiveWorks::AutoInvoke::Client # use strict; package Calculator; use base qw( SOAP::Transport::ActiveWorks::AutoInvoke::Client ); package main; my $calc = new Calculator; print "sum = ", $calc->add ( 1, 2, 3 ), "\n"; DESCRIPTION =========== The intention of the AutoInvoke package is to allow a SOAP client to use a remote class as if it were local. The remote package is treated as local with a declaration like: package MyClass; use base qw( SOAP::Transport::ActiveWorks::AutoInvoke::Client ); The SOAP::AutoInvoke base class will "Autoload" methods called from an instance of "MyClass", send it to the server side, and return the results to the caller's space. Provided Methods ---------------- new: * * The 'new' method may be called with option arguments to reset variables from the defaults. my $class = new MyClass ( _soap_host => 'anywhere.com', _soap_port => 8849, _soap_client_group => 'NotSOAP', _soap_method_uri => 'urn:com-name-your' ); It is advisable to set the package defaults at installation time in the SOAP/Transport/ActiveWorks/AutoInvoke/Client.pm (this) file. The variables may also be reset after instantiation with the 'set' methods. The '_soap_' variable is relevant only to the local instantiation of "MyClass". The remote instantiation will call "new" with any arguments you have passed to the local instantiation that did not begin with '_soap_': my $class = new MyClass ( _soap_host => 'anywhere.com', arg1, arg2, @arg3, arg4 => $value, : ); This works so long as the data types being passed are something the SOAP package can serialize. SOAP::AutoInvoke can send and receive simple arrays. To reset the name of the "new" to be called remotely: my $class = new MyClass ( : _soap_new_method => 'create', : ); To not call any new method remotely: my $class = new MyClass ( : _soap_new_method => undef, : ); *_soap_get_post*: returns the contents of $class->{_soap_host}. *_soap_set_post*: sets the contents of $class->{_soap_host}. *_soap_get_port*: returns the contents of $class->{_soap_port}. *_soap_set_port*: sets the contents of $class->{_soap_port}. *_soap_get_broker*: returns the contents of $class->{_soap_broker}. *_soap_set_broker*: sets the contents of $class->{_soap_broker}. *_soap_get_client_group*: returns the contents of $class->{_soap_client_group}. *_soap_set_client_group*: sets the contents of $class->{_soap_client_group}. *_soap_get_method_uri*: returns the contents of $class->{_soap_method_uri}. *_soap_set_method_uri*: sets the contents of $class->{_soap_method_uri}. *_soap_get_new_args*: returns the contents of $class->{_soap_new_args}. *_soap_set_new_args*: sets the contents of $class->{_soap_new_args}. *_soap_get_new_method*: returns the contents of $class->{_soap_new_method}. *_soap_set_new_method*: sets the contents of $class->{_soap_new_method}. The default is "new". DEPENDENCIES ============ SOAP-0.28 SOAP::Transport::ActiveWorks Data::Dumper AUTHOR ====== Daniel Yacob, `yacob@rcn.com|mailto:yacob@rcn.com' in this node SEE ALSO ======== perl(1). SOAP(3). SOAP::Transport::ActiveWorks::AutoInvoke::Server(3).  File: pm.info, Node: SOAP/Transport/ActiveWorks/AutoInvoke/Server, Next: SOAP/Transport/ActiveWorks/Client, Prev: SOAP/Transport/ActiveWorks/AutoInvoke/Client, Up: Module List Automarshall methods for Perl SOAP ********************************** NAME ==== SOAP::Transport::ActiveWorks::AutoInvoke::Server - Automarshall methods for Perl SOAP SYNOPSIS ======== require SOAP::Transport::ActiveWorks::Server; use SOAP::Transport::ActiveWorks::AutoInvoke::Server; my $safe_classes ={ Calculator => \&auto_invoke, Time => \&handle_time_request, }; DESCRIPTION =========== SOAP::Transport::ActiveWorks::AutoInvoke::Server provides the dispatch subroutine "auto_invoke" to handle class instantiation and method invocation that were called with a client created with SOAP::Transport::ActiveWorks::AutoInvoke::Client. Intended use is with SOAP adapters. DEPENDENCIES ============ SOAP-0.28 SOAP::Transport::ActiveWorks SOAP::Transport::ActiveWorks::AutoInvoke::Client Data::Dumper AUTHOR ====== Daniel Yacob, `yacob@rcn.com|mailto:yacob@rcn.com' in this node SEE ALSO ======== perl(1). SOAP(3). SOAP::Transport::ActiveWorks::AutoInvoke::Client(3).  File: pm.info, Node: SOAP/Transport/ActiveWorks/Client, Next: SOAP/Transport/ActiveWorks/Defs, Prev: SOAP/Transport/ActiveWorks/AutoInvoke/Server, Up: Module List Client side ActiveWorks support for SOAP/Perl ********************************************* NAME ==== SOAP::Transport::ActiveWorks::Client - Client side ActiveWorks support for SOAP/Perl SYNOPSIS ======== use SOAP::Transport::ActiveWorks::Client; my $soap_on_aw = SOAP::Transport::ActiveWorks::Client->new(); my $soap_response = $soap_on_aw->send_receive ( $self->{_soap_host}, $self->{_soap_port}, $self->{_soap_broker}, $self->{_soap_client_group}, $self->{_soap_class}, $self->{_soap_method_uri}, $method_name, $soap_request ); DESCRIPTION =========== SOAP::Transport::ActiveWorks::Client provides a client class with the single method "send_receive" to deliver a SOAP formatted request to a SOAP adapter connected to an ActiveWorks broker. The ActiveWorks SOAP client is the direct analog to the HTTP Client. The primary difference is that the "endpoint" is split into fields specifying the "broker" and "client_group" to connect to. These attributes may be set when the client object is instantiated or at any time afterwards. Not specifiying a values defaults to the settings in SOAP::Transport::ActiveWorks::Defs. DEPENDENCIES ============ Aw::Client SOAP-0.28 SOAP::Defs SOAP::Transport::ActiveWorks::Defs; AUTHOR ====== Daniel Yacob, `yacob@rcn.com|mailto:yacob@rcn.com' in this node SEE ALSO ======== perl(1). SOAP(3). SOAP::Transport::ActiveWorks::Server(3).  File: pm.info, Node: SOAP/Transport/ActiveWorks/Defs, Next: SOAP/Transport/ActiveWorks/HTTP/Apache, Prev: SOAP/Transport/ActiveWorks/Client, Up: Module List Spec-defined constants ********************** NAME ==== SOAP::Transport::ActiveWorks::Defs - Spec-defined constants SYNOPSIS ======== use SOAP::Transport::ActiveWorks::Defs; DESCRIPTION =========== This is an internal class that exports global symbols needed by various SOAP/ActiveWorks/Perl classes. You don't need to import this module directly unless you happen to be building SOAP plumbing (as opposed to simply writing a SOAP client or server). AUTHOR ====== Daniel Yacob, `yacob@rcn.com|mailto:yacob@rcn.com' in this node SEE ALSO ======== perl(1). SOAP(3). SOAP::Transport::ActiveWorks::Server(3).  File: pm.info, Node: SOAP/Transport/ActiveWorks/HTTP/Apache, Next: SOAP/Transport/ActiveWorks/HTTP/Proxy, Prev: SOAP/Transport/ActiveWorks/Defs, Up: Module List Forward SOAP requests from Apache to an ActiveWorks broker ********************************************************** NAME ==== SOAP::Transport::ActiveWorks::HTTP::Apache - Forward SOAP requests from Apache to an ActiveWorks broker SYNOPSIS ======== package Apache::SOAPServer; use strict; use Apache; use SOAP::Transport::HTTP::Apache; use SOAP::Transport::ActiveWorks::HTTP::Apache; sub handler { my $http_safe_classes = { ClassA => undef, ClassB => undef, }; my $aw_safe_classes = { ClassC => undef, Calculator => undef, }; my $r = Apache->request(); my %args = $r->args(); if ( $http_safe_classes->{$args{class}} ) { # # Handle requests here and now. # SOAP::Transport::HTTP::Apache->handler($http_safe_classes); } else { # # Forward to an adapter for handling. # SOAP::Transport::ActiveWorks::HTTP::Apache->handler($aw_safe_classes); } } DESCRIPTION =========== This package is a minor rewrite of the SOAP::Transport::HTTP::Apache. The difference is that it uses a proxy handler to forward requests to an ActiveWorks broker instead the HTTP server handler. DEPENDENCIES ============ SOAP::Transport::HTTP::Server; AUTHOR ====== Daniel Yacob, `yacob@rcn.com|mailto:yacob@rcn.com' in this node SEE ALSO ======== perl(1). SOAP(3). SOAP::Transport::ActiveWorks::HTTP::Proxy(3).  File: pm.info, Node: SOAP/Transport/ActiveWorks/HTTP/Proxy, Next: SOAP/Transport/ActiveWorks/Server, Prev: SOAP/Transport/ActiveWorks/HTTP/Apache, Up: Module List Forward SOAP requests from an HTTP server to an ActiveWorks broker ****************************************************************** NAME ==== SOAP::Transport::ActiveWorks::HTTP::Proxy - Forward SOAP requests from an HTTP server to an ActiveWorks broker SYNOPSIS ======== require SOAP::Transport::HTTP::Proxy; my $s = SOAP::Transport::ActiveWorks::HTTP::Proxy->new(); $s->handle_request($http_method, $request_class, $request_header_reader, $request_content_reader, $response_header_writer, $response_content_writer, $optional_dispatcher); DESCRIPTION =========== SOAP::Transport::ActiveWorks::HTTP::Proxy provides a handler for use by SOAP::Transport::ActiveWorks::HTTP::Apache for forwarding requests to an ActiveWorks broker received via Apache or other HTTP server. The relationship between packages is identical to that of SOAP::Transport::::HTTP::Apache/Server. See SOAP::Transport::ActiveWorks::HTTP::Apache for intended usage. The package also provides a subroutine for optional usage as dispatcher. http_proxy ---------- * * The subroutine http_proxy may be imported from the package to use with SOAP::Transport::HTTP::Apache directly as an optional_dispatcher. Optional dispatcher usage as shown below is valid with the version of SOAP::Transport::HTTP::Apache that comes with the SOAP-AutoInvoke package: package Apache::SOAPServer; use strict; use Apache; use SOAP::Transport::HTTP::Apache; use SOAP::Transport::ActiveWorks::HTTP::Proxy qw( http_proxy ); sub handler { my $safe_classes ={ ClassA => undef, ClassB => undef, Calculator => \&http_proxy, }; SOAP::Transport::HTTP::Apache->handler($safe_classes); } DEPENDENCIES ============ SOAP::Defs SOAP::Parser SOAP::EnvelopeMaker SOAP::Transport::ActiveWorks::Defs AUTHOR ====== Daniel Yacob, `yacob@rcn.com|mailto:yacob@rcn.com' in this node SEE ALSO ======== perl(1). SOAP(3). SOAP::Transport::ActiveWorks::HTTP::Apache(3).  File: pm.info, Node: SOAP/Transport/ActiveWorks/Server, Next: SOAP/Transport/FTP, Prev: SOAP/Transport/ActiveWorks/HTTP/Proxy, Up: Module List Server side ActiveWorks support for SOAP/Perl ********************************************* NAME ==== SOAP::Transport::ActiveWorks::Server - Server side ActiveWorks support for SOAP/Perl SYNOPSIS ======== require SOAP::Transport::ActiveWorks::Server; my $s = new SOAP::Transport::ActiveWorks::Server; $s->handle_request ( $request_type, $request_class, $request_header_reader, $request_content_reader, $response_header_writer, $response_content_writer, $optional_dispatcher ); DESCRIPTION =========== This package is a minimalist wrapper around SOAP::Transport::HTTP::Server which may be substituted for this package with no loss of functionality. This is not guaranteed to be the case in the future. DEPENDENCIES ============ SOAP::Transport::HTTP::Server; AUTHOR ====== Daniel Yacob, `yacob@rcn.com|mailto:yacob@rcn.com' in this node SEE ALSO ======== perl(1). SOAP(3). SOAP::Transport::ActiveWorks::Client(3).  File: pm.info, Node: SOAP/Transport/FTP, Next: SOAP/Transport/HTTP, Prev: SOAP/Transport/ActiveWorks/Server, Up: Module List Client side FTP support for SOAP::Lite ************************************** NAME ==== SOAP::Transport::FTP - Client side FTP support for SOAP::Lite SYNOPSIS ======== use SOAP::Lite uri => 'http://my.own.site.com/My/Examples', proxy => 'ftp://login:password@ftp.somewhere.com/relative/path/to/file.xml', # ftp server # proxy => 'ftp://login:password@ftp.somewhere.com//absolute/path/to/file.xml', # ftp server ; print getStateName(1); DESCRIPTION =========== COPYRIGHT ========= Copyright (C) 2000-2001 Paul Kulchenko. All rights reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. AUTHOR ====== Paul Kulchenko (paulclinger@yahoo.com)  File: pm.info, Node: SOAP/Transport/HTTP, Next: SOAP/Transport/HTTP/Apache, Prev: SOAP/Transport/FTP, Up: Module List Server/Client side HTTP support for SOAP::Lite ********************************************** NAME ==== SOAP::Transport::HTTP - Server/Client side HTTP support for SOAP::Lite SYNOPSIS ======== Client use SOAP::Lite uri => 'http://my.own.site.com/My/Examples', proxy => 'http://localhost/', # proxy => 'http://localhost/cgi-bin/soap.cgi', # local CGI server # proxy => 'http://localhost/', # local daemon server # proxy => 'http://localhost/soap', # local mod_perl server # proxy => 'https://localhost/soap', # local mod_perl SECURE server # proxy => 'http://login:password@localhost/cgi-bin/soap.cgi', # local CGI server with authentication ; print getStateName(1); CGI server use SOAP::Transport::HTTP; SOAP::Transport::HTTP::CGI # specify path to My/Examples.pm here -> dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method') -> handle ; 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; Apache mod_perl server See `examples/server/Apache.pm' and `' in this node section for more information. mod_soap server (.htaccess, directory-based access) SetHandler perl-script PerlHandler Apache::SOAP PerlSetVar dispatch_to "/Your/Path/To/Deployed/Modules, Module::Name, Module::method" PerlSetVar options "compress_threshold => 10000" See *Note Apache/SOAP: Apache/SOAP, for more information. DESCRIPTION =========== This class encapsulates all HTTP related logic for a SOAP server, independent of what web server it's attached to. If you want to use this class you should follow simple guideline mentioned above. Following methods are available: on_action() on_action method lets you specify SOAPAction understanding. It accepts reference to subroutine that takes three parameters: SOAPAction, method_uri and method_name. `SOAPAction' is taken from HTTP header and method_uri and method_name are extracted from request's body. Default behavior is match `SOAPAction' if present and ignore it otherwise. You can specify you own, for example die if `SOAPAction' doesn't match with following code: $server->on_action(sub { (my $action = shift) =~ s/^("?)(.+)\1$/$2/; die "SOAPAction shall match 'uri#method'\n" if $action ne join '#', @_; }); dispatch_to() dispatch_to lets you specify where you want to dispatch your services to. More precisely, you can specify PATH, MODULE, method or combination `MODULE::method'. Example: dispatch_to( 'PATH/', # dynamic: load anything from there, any module, any method 'MODULE', # static: any method from this module 'MODULE::method', # static: specified method from this module 'method', # static: specified method from main:: ); If you specify `PATH/' name of module/classes will be taken from uri as path component and converted to Perl module name with substitution '::' for '/'. Example: urn:My/Examples => My::Examples urn://localhost/My/Examples => My::Examples http://localhost/My/Examples => My::Examples For consistency first '/' in the path will be ignored. According to this scheme to deploy new class you should put this class in one of the specified directories and enjoy its services. Easy, eh? handle() handle method will handle your request. You should provide parameters with request() method, call handle() and get it back with response() . request() request method gives you access to HTTP::Request object which you can provide for Server component to handle request. response() response method gives you access to HTTP::Response object which you can access to get results from Server component after request was handled. PROXY SETTINGS -------------- You can use any proxy setting you use with LWP::UserAgent modules: SOAP::Lite->proxy('http://endpoint.server', proxy => ['http' => 'http://my.proxy.server']); or $soap->transport->proxy('http' => 'http://my.proxy.server'); should specify proxy server for you. And if you use `HTTP_proxy_user' and `HTTP_proxy_pass' for proxy authorization SOAP::Lite should know how to handle it properly. COOKIE-BASED AUTHENTICATION --------------------------- 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); Cookies will be taken from response and provided for request. You may always add another cookie (or extract what you need after response) with HTTP::Cookies interface. You may also do it in one line: $soap->proxy('http://localhost', cookie_jar => HTTP::Cookies->new(ignore_discard => 1)); COMPRESSION ----------- SOAP::Lite provides you option for enabling compression on wire (for HTTP transport only). Both server and client should support this capability, but this logic should be absolutely transparent for your application. Server will respond with encoded message only if client can accept it (client sends Accept-Encoding with 'compress' or '*' values) and client has fallback logic, so if server doesn't understand specified encoding (Content-Encoding: compress) and returns proper error code (406 NOT ACCEPTABLE) client will repeat the same request not encoded and will store this server in per-session cache, so all other requests will go there without encoding. Having options on client and server side that let you specify threshold for compression you can safely enable this feature on both client and server side. Client print SOAP::Lite -> uri('http://localhost/My/Parameters') -> proxy('http://localhost/', options => {compress_threshold => 10000}) -> echo(1 x 10000) -> result ; Server my $server = SOAP::Transport::HTTP::CGI -> dispatch_to('My::Parameters') -> options({compress_threshold => 10000}) -> handle; Compression will be enabled on client side IF: threshold is specified AND size of current message is bigger than threshold AND module Compress::Zlib is available. Client will send header 'Accept-Encoding' with value 'compress' if threshold is specified AND module Compress::Zlib is available. Server will accept compressed message if module Compress::Zlib is available, and will respond with compressed message ONLY IF: threshold is specified AND size of current message is bigger than threshold AND module Compress::Zlib is available AND header 'Accept-Encoding' is presented in request. EXAMPLES ======== Consider following examples of SOAP servers: CGI: use SOAP::Transport::HTTP; SOAP::Transport::HTTP::CGI -> dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method') -> handle ; daemon: use SOAP::Transport::HTTP; my $daemon = SOAP::Transport::HTTP::Daemon -> new (LocalAddr => 'localhost', LocalPort => 80) -> dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method') ; print "Contact to SOAP server at ", $daemon->url, "\n"; $daemon->handle; mod_perl: httpd.conf: SetHandler perl-script PerlHandler SOAP::Apache 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; Apache::Registry: httpd.conf: Alias /mod_perl/ "/Apache/mod_perl/" SetHandler perl-script PerlHandler Apache::Registry PerlSendHeader On Options +ExecCGI soap.mod_cgi (put it in /Apache/mod_perl/ directory mentioned above) use SOAP::Transport::HTTP; SOAP::Transport::HTTP::CGI -> dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method') -> handle ; WARNING: dynamic deployment with Apache::Registry will fail, because module will be loaded dynamically only for the first time. After that it is already in the memory, that will bypass dynamic deployment and produces error about denied access. Specify both PATH/ and MODULE name in dispatch_to() and module will be loaded dynamically and then will work as under static deployment. See examples/server/soap.mod_cgi for example. TROUBLESHOOTING =============== Dynamic libraries are not found If you see in webserver's log file something like this: Can't load '/usr/local/lib/perl5/site_perl/.../XML/Parser/Expat/Expat.so' for module XML::Parser::Expat: dynamic linker: /usr/local/bin/perl: libexpat.so.0 is NEEDED, but object does not exist at /usr/local/lib/perl5/.../DynaLoader.pm line 200. and you are using Apache web server, try to put into your httpd.conf PassEnv LD_LIBRARY_PATH Apache is crashing with segfaults If using SOAP::Lite (or XML::Parser::Expat) in combination with mod_perl causes random segmentation faults in httpd processes try to configure Apache with: RULE_EXPAT=no See http://archive.covalent.net/modperl/2000/04/0185.xml for more details and lot of thanks to Robert Barta (rho@bigpond.net.au) for explaining this weird behavior. CGI scripts are not running under Microsoft Internet Information Server (IIS) CGI scripts may not work under IIS unless scripts are .pl, not .cgi. DEPENDENCIES ============ Crypt::SSLeay for HTTPS/SSL SOAP::Lite, URI for SOAP::Transport::HTTP::Server LWP::UserAgent, URI for SOAP::Transport::HTTP::Client HTTP::Daemon for SOAP::Transport::HTTP::Daemon Apache, Apache::Constants for SOAP::Transport::HTTP::Apache SEE ALSO ======== See ::CGI, ::Daemon and ::Apache for implementation details. See examples/server/soap.cgi as SOAP::Transport::HTTP::CGI example. See examples/server/soap.daemon as SOAP::Transport::HTTP::Daemon example. See examples/My/Apache.pm as SOAP::Transport::HTTP::Apache example. COPYRIGHT ========= Copyright (C) 2000-2001 Paul Kulchenko. All rights reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. AUTHOR ====== Paul Kulchenko (paulclinger@yahoo.com)  File: pm.info, Node: SOAP/Transport/HTTP/Apache, Next: SOAP/Transport/HTTP/AutoInvoke/Client, Prev: SOAP/Transport/HTTP, Up: Module List SOAP mod_perl handler ********************* NAME ==== SOAP::Transport::HTTP::Apache - SOAP mod_perl handler SYNOPSIS ======== Use this class to expose SOAP endpoints using Apache and mod_perl. Here's an example of a class that would like to receive SOAP packets. Note that it implements a single interesting function, handle_request, that takes there arguments: an array of headers, a body, and an EnvelopeMaker for creating the response: package Calculator; use strict; sub new { bless {}, shift; } sub handle_request { my ($self, $headers, $body, $envelopeMaker) = @_; $body->{extra_stuff} = "heres some extra stuff"; foreach my $header (@$headers) { $header->{extra_stuff} = "heres some more extra stuff"; $envelopeMaker->add_header(undef, undef, 0, 0, $header); } $envelopeMaker->set_body(undef, 'myresponse', 0, $body); } 1; In order to translate HTTP requests into calls on your Calculator class above, you'll need to write an Apache handler. This is where you'll use the SOAP::Transport::HTTP::Apache class: package ServerDemo; use strict; use SOAP::Transport::HTTP::Apache; sub handler { my $safe_classes = { Calculator => undef, }; SOAP::Transport::HTTP::Apache->handler($safe_classes); } 1; As you can see, this class basically does it all - parses the HTTP headers, reads the request, and sends a response. All you have to do is specify the names of classes that are safe to dispatch to. Of course, in order to tell Apache about your handler class above, you'll need to modify httpd.conf. Here's a simple example that shows how to set up an endpoint called "/soap" that maps to your ServerDemo handler above: SetHandler perl-script PerlHandler ServerDemo (I leave it up to you to make sure ServerDemo is in Perl's @INC path - see Writing Apache Modules with Perl and C by O'Reilly for help with mod_perl, or just man mod_perl) DESCRIPTION =========== This class encapsulates the details of hooking up to mod_perl, and then calls SOAP::Transport::HTTP::Server to do the SOAP-specific stuff. This way the Server class can be reused with any web server configuration (including CGI), by simply composing it with a different front-end (for instance, SOAP::Transport::HTTP::CGI). handler(SafeClassHash, OptionalDispatcher) ------------------------------------------ This is the only method on the class, and you must pass a hash reference whose keys contain the collection of classes that may be invoked at this endpoint. If you specify class FooBar in this list, for instance, and a client sends a SOAP request to http://yourserver/soap?class=FooBar, then the SOAP::Transport::HTTP::Server class will eventually attempt to load FooBar.pm, instatiate a FooBar, and call its handle_request function (see SOAP::Transport::HTTP::Server for more detail). If you don't include a class in this hash, SOAP/Perl won't run it. I promise. By the way, only the keys in this hash are important, the values are ignored. Also, nothing is stopping you from messing around with the request object yourself if you'd like to add some headers or whatever; you can always call Apache->request() to get the request object inside your handle_request function. Just make sure you finish what you're doing before you return to SOAP::Transport::HTTP::Server, because at that point the response is marshaled and sent back. See SOAP::Transport::HTTP::Server for a description of the OptionalDispatcher argument. DEPENDENCIES ============ SOAP::Transport::HTTP::Server AUTHOR ====== Keith Brown