1# ====================================================================== 2# 3# Copyright (C) 2000-2003 Paul Kulchenko (paulclinger@yahoo.com) 4# SOAP::Lite is free software; you can redistribute it 5# and/or modify it under the same terms as Perl itself. 6# 7# $Id: Lite.pm 95 2007-10-09 09:10:44Z kutterma $ 8# 9# ====================================================================== 10 11=pod 12 13=head1 NAME 14 15SOAP::Lite - Client and server side SOAP implementation 16 17=head1 SYNOPSIS 18 19 use SOAP::Lite; 20 print SOAP::Lite 21 -> uri('http://www.soaplite.com/Temperatures') 22 -> proxy('http://services.soaplite.com/temper.cgi') 23 -> f2c(32) 24 -> result; 25 26The same code with autodispatch: 27 28 use SOAP::Lite +autodispatch => 29 uri => 'http://www.soaplite.com/Temperatures', 30 proxy => 'http://services.soaplite.com/temper.cgi'; 31 32 print f2c(32); 33 34Code in OO-style: 35 36 use SOAP::Lite +autodispatch => 37 uri => 'http://www.soaplite.com/Temperatures', 38 proxy => 'http://services.soaplite.com/temper.cgi'; 39 40 my $temperatures = Temperatures->new(32); # get object 41 print $temperatures->as_celsius; # invoke method 42 43Code with service description: 44 45 use SOAP::Lite; 46 print SOAP::Lite 47 -> service('http://www.xmethods.net/sd/StockQuoteService.wsdl') 48 -> getQuote('MSFT'); 49 50Code for SOAP server (CGI): 51 52 use SOAP::Transport::HTTP; 53 SOAP::Transport::HTTP::CGI 54 -> dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method') 55 -> handle; 56 57Visual Basic client (through COM interface): 58 59 MsgBox CreateObject("SOAP.Lite").new( _ 60 "proxy", "http://services.xmethods.net/soap", _ 61 "uri", "urn:xmethods-delayed-quotes" _ 62 ).getQuote("MSFT").result 63 64mod_soap enabled SOAP server: 65 66 .htaccess 67 68 SetHandler perl-script 69 PerlHandler Apache::SOAP 70 PerlSetVar dispatch_to "/Your/Path/To/Deployed/Modules, Module::Name" 71 72ASP/VB SOAP server: 73 74 <% 75 Response.ContentType = "text/xml" 76 Response.Write(Server.CreateObject("SOAP.Lite") _ 77 .server("SOAP::Server") _ 78 .dispatch_to("/Your/Path/To/Deployed/Modules") _ 79 .handle(Request.BinaryRead(Request.TotalBytes)) _ 80 ) 81 %> 82 83=head1 DESCRIPTION 84 85SOAP::Lite is a collection of Perl modules which provides a 86simple and lightweight interface to the Simple Object Access Protocol 87(SOAP) both on client and server side. 88 89This version of SOAP::Lite supports the SOAP 1.1 specification ( http://www.w3.org/TR/SOAP ). 90 91The main features of the library are: 92 93=over 3 94 95=item * 96 97Supports SOAP 1.1 spec. 98 99=item * 100 101Interoperability tests with different implementations: Apache SOAP, Apache Axis, Frontier, Microsoft SOAP, Microsoft .NET, DevelopMentor, XMethods, 4s4c, Phalanx, PocketSOAP, Kafka, SQLData, Lucin (in Java, Perl, C++, Python, VB, COM, XSLT). 102 103=item * 104 105Provides COM interface. Single dll (standalone [2.5MB] or minimal [32kB]). 106Works on Windows 9x/Me/NT/2K. Doesn't require ROPE or MSXML. 107Examples in VB, Excel/VBA, C#, ASP, JavaScript, PerlScript and Perl. 108 109=item * 110 111Provides transparent compression support for HTTP transport. 112 113=item * 114 115Provides mod_soap module. Make SOAP server with a few lines in .htaccess 116or .conf file. 117 118=item * 119 120Includes XML::Parser::Lite (regexp-based XML parser) which runs instead 121of XML::Parser where Perl 5.6 runs (even on WinCE) with some limitations. 122 123=item * 124 125Includes XMLRPC::Lite, implementation of XML-RPC protocol on client and 126server side. All transports and features of SOAP::Lite are available. 127 128=item * 129 130Supports multipart/form-data MIME attachments. 131 132=item * 133 134Supports circular linked lists and multiple references. 135 136=item * 137 138Supports Map datatype (encoding of maps/hashes with arbitrary keys). 139 140=item * 141 142Supports HTTPS protocol. 143 144=item * 145 146Provides proxy support. 147 148=item * 149 150Provides CGI/daemon/mod_perl/Apache::Registry server implementations. 151 152=item * 153 154Provides TCP server implementation. 155 156=item * 157 158Provides IO (STDIN/STDOUT/File) server implementation. 159 160=item * 161 162Provides FTP client implementation. 163 164=item * 165 166Supports single/multipart MIME attachment (parsing side only). 167 168=item * 169 170Supports SMTP protocol. 171 172=item * 173 174Provides POP3 server implementation. 175 176=item * 177 178Supports M-POST and redirects in HTTP transport. 179 180=item * 181 182Supports Basic/Digest server authentication. 183 184=item * 185 186Works with CGI accelerators, like VelociGen and PerlEx. 187 188=item * 189 190Supports UDDI interface on client side. See UDDI::Lite for details. 191 192=item * 193 194Supports UDDI publishing API. Examples and documentation provided. 195 196=item * 197 198Supports WSDL schema with stub and run-time access. 199 200=item * 201 202Supports blessed object references. 203 204=item * 205 206Supports arrays (both serialization and deserialization with autotyping). 207 208=item * 209 210Supports custom serialization. 211 212=item * 213 214Provides exception transport with custom exceptions 215 216=item * 217 218Supports Base64 encoding. 219 220=item * 221 222Supports XML entity encoding. 223 224=item * 225 226Supports header attributes. 227 228=item * 229 230Supports dynamic and static class/method binding. 231 232=item * 233 234Supports objects-by-reference with simple garbage collection and activation. 235 236=item * 237 238Provides shell for interactive SOAP sessions. 239 240=item * 241 242Supports out parameters binding. 243 244=item * 245 246Supports transparent SOAP calls with autodispatch feature. 247 248=item * 249 250Provides easy services deployment. Put module in specified directory and 251it'll be accessible. 252 253=item * 254 255Has tests, examples and documentation to let you be up and running in no time. 256 257=back 258 259=head2 WHERE TO FIND EXAMPLES 260 261See F<t/*.t>, F<examples/*.pl> and the module documentation for a client-side 262examples that demonstrate the serialization of a SOAP request, sending it 263via HTTP to the server and receiving the response, and the deserialization 264of the response. See F<examples/server/*> for server-side implementations. 265 266=head1 OVERVIEW OF CLASSES AND PACKAGES 267 268This table should give you a quick overview of the classes provided by the 269library. 270 271 SOAP::Lite.pm 272 -- SOAP::Lite -- Main class provides all logic 273 -- SOAP::Transport -- Supports transport architecture 274 -- SOAP::Data -- Provides extensions for serialization architecture 275 -- SOAP::Header -- Provides extensions for header serialization 276 -- SOAP::Parser -- Parses XML file into object tree 277 -- SOAP::Serializer -- Serializes data structures to SOAP package 278 -- SOAP::Deserializer -- Deserializes results of SOAP::Parser into objects 279 -- SOAP::SOM -- Provides access to deserialized object tree 280 -- SOAP::Constants -- Provides access to common constants 281 -- SOAP::Trace -- Provides tracing facilities 282 -- SOAP::Schema -- Provides access and stub(s) for schema(s) 283 -- SOAP::Schema::WSDL -- WSDL implementation for SOAP::Schema 284 -- SOAP::Server -- Handles requests on server side 285 -- SOAP::Server::Object -- Handles objects-by-reference 286 -- SOAP::Fault -- Provides support for Faults on server side 287 -- SOAP::Utils -- A set of private and public utility subroutines 288 289 SOAP::Transport::HTTP.pm 290 -- SOAP::Transport::HTTP::Client -- Client interface to HTTP transport 291 -- SOAP::Transport::HTTP::Server -- Server interface to HTTP transport 292 -- SOAP::Transport::HTTP::CGI -- CGI implementation of server interface 293 -- SOAP::Transport::HTTP::Daemon -- Daemon implementation of server interface 294 -- SOAP::Transport::HTTP::Apache -- mod_perl implementation of server interface 295 296 SOAP::Transport::POP3.pm 297 -- SOAP::Transport::POP3::Server -- Server interface to POP3 protocol 298 299 SOAP::Transport::MAILTO.pm 300 -- SOAP::Transport::MAILTO::Client -- Client interface to SMTP/sendmail 301 302 SOAP::Transport::LOCAL.pm 303 -- SOAP::Transport::LOCAL::Client -- Client interface to local transport 304 305 SOAP::Transport::TCP.pm 306 -- SOAP::Transport::TCP::Server -- Server interface to TCP protocol 307 -- SOAP::Transport::TCP::Client -- Client interface to TCP protocol 308 309 SOAP::Transport::IO.pm 310 -- SOAP::Transport::IO::Server -- Server interface to IO transport 311 312=head2 SOAP::Lite 313 314All methods that C<SOAP::Lite> provides can be used for both 315setting and retrieving values. If you provide no parameters, you will 316get current value, and if parameters are provided, a new value 317will be assigned to the object and the method in question will return 318the current object (if not stated otherwise). This is suitable for stacking 319these calls like: 320 321 $lite = SOAP::Lite 322 -> uri('http://simon.fell.com/calc') 323 -> proxy('http://soap.4s4c.com/ssss4c/soap.asp') 324 ; 325 326The order is insignificant and you may call the new() method first. If you 327don't do it, SOAP::Lite will do it for you. However, the new() method 328gives you an additional syntax: 329 330 $lite = new SOAP::Lite 331 uri => 'http://simon.fell.com/calc', 332 proxy => 'http://soap.4s4c.com/ssss4c/soap.asp' 333 ; 334 335=over 4 336 337=item new() 338 339new() accepts a hash with method names as keys. It will call the 340appropriate methods together with the passed values. Since new() is 341optional it won't be mentioned anymore. 342 343=item transport() 344 345Provides access to the L</"SOAP::Transport"> object. The object will be created 346for you. You can reassign it (but generally you should not). 347 348=item serializer() 349 350Provides access to the L</"SOAP::Serializer"> object. The object will be 351created for you. You can reassign it (but generally you should not). 352 353=item proxy() 354 355Shortcut for C<< transport->proxy() >>. This lets you specify an endpoint 356(service address) and also loads the required module at the same time. It is 357required for dispatching SOAP calls. The name of the module will be defined 358depending on the protocol specific for the endpoint. The prefix 359C<SOAP::Transport> will be prepended, the module will be loaded and object of 360class (with appended C<::Client>) will be created. 361 362For example, for F<http://localhost/>, the class for creating objects will 363look for C<SOAP::Transport:HTTP::Client>; 364 365In addition to endpoint parameter, proxy() can accept any transport specific 366parameters that could be passed as name => value pairs. For example, to 367specify proxy settings for HTTP protocol you may do: 368 369 $soap->proxy('http://endpoint.server/', 370 proxy => ['http' => 'http://my.proxy.server/']); 371 372Notice that since proxy (second one) expects to get more than one 373parameter you should wrap them in array. 374 375Another useful example can be the client that is sensitive to cookie-based 376authentication. You can provide this with: 377 378 $soap->proxy('http://localhost/', 379 cookie_jar => HTTP::Cookies->new(ignore_discard => 1)); 380 381You may specify timeout for HTTP transport with following code: 382 383 $soap->proxy('http://localhost/', timeout => 5); 384 385=item endpoint() 386 387Lets you specify an endpoint B<without> changing/loading the protocol module. 388This is useful for switching endpoints without switching protocols. You should 389call C<proxy()> first. No checks for protocol equivalence will be made. 390 391=item outputxml() 392 393Lets you specify the kind of output from all method calls. If C<true>, all 394methods will return unprocessed, raw XML code. You can parse it with 395XML::Parser, SOAP::Deserializer or any other appropriate module. 396 397=item autotype() 398 399Shortcut for C<< serializer->autotype() >>. This lets you specify whether 400the serializer will try to make autotyping for you or not. Default setting 401is C<true>. 402 403=item readable() 404 405Shortcut for C<< serializer->readable() >>. This lets you specify the format 406for the generated XML code. Carriage returns <CR> and indentation will be 407added for readability. Useful in the case you want to see the generated code 408in a debugger. By default, there are no additional characters in generated 409XML code. 410 411=item use_prefix() 412 413Shortcut for C<< serializer->use_prefix() >>. This lets you turn on/off the 414use of a namespace prefix for the children of the /Envelope/Body element. 415Default is 'true'. (This was introduced in 0.61 for better .NET compatibility) 416 417When use_prefix is set to 'true', serialized XML will look like this: 418 419 <SOAP-ENV:Envelope ...attributes skipped> 420 <SOAP-ENV:Body> 421 <namesp1:mymethod xmlns:namesp1="urn:MyURI" /> 422 </SOAP-ENV:Body> 423 </SOAP-ENV:Envelope> 424 425When use_prefix is set to 'false', serialized XML will look like this: 426 427 <SOAP-ENV:Envelope ...attributes skipped> 428 <SOAP-ENV:Body> 429 <mymethod xmlns="urn:MyURI" /> 430 </SOAP-ENV:Body> 431 </SOAP-ENV:Envelope> 432 433=item namespace() 434 435Shortcut for C<< serializer->namespace() >>. This lets you specify the default 436namespace for generated envelopes (C<'SOAP-ENV'> by default). 437 438=item encodingspace() 439 440Shortcut for C<< serializer->encodingspace() >>. This lets you specify the 441default encoding namespace for generated envelopes (C<'SOAP-ENC'> by default). 442 443=item encoding() 444 445Shortcut for C<< serializer->encoding() >>. This lets you specify the encoding 446for generated envelopes. It does not actually change envelope 447encoding, it will just modify the XML declaration (C<'UTF-8'> by default). 448Use C<undef> value to B<not> generate XML declaration. 449 450=item typelookup() 451 452Shortcut for C<< serializer->typelookup() >>. This gives you access to 453the C<typelookup> table that is used for autotyping. For more information 454see L</"SOAP::Serializer">. 455 456=item uri() 457 458Shortcut for C<< serializer->uri() >>. This lets you specify the uri for SOAP 459methods. Nothing is specified by default and your call will definitely fail 460if you don't specify the required uri. 461 462B<WARNING>: URIs are just identifiers. They may B<look like URLs>, but they are 463not guaranteed to point to anywhere and shouldn't be used as such pointers. 464URIs assume to be unique within the space of all XML documents, so consider 465them as unique identifiers and nothing else. 466 467=item multirefinplace() 468 469Shortcut for C<< serializer->multirefinplace() >>. If true, the serializer will 470put values for multireferences in the first occurrence of the reference. 471Otherwise it will be encoded as top independent element, right after C<method> 472element inside C<Body>. Default value is C<false>. 473 474=item header() 475 476B<DEPRECATED>: Use SOAP::Header instead. 477 478Shortcut for C<< serializer->header() >>. This lets you specify the header for 479generated envelopes. You can specify C<root>, C<mustUnderstand> or any 480other header using L</"SOAP::Data"> class: 481 482 $serializer = SOAP::Serializer->envelope('method' => 'mymethod', 1, 483 SOAP::Header->name(t1 => 5)->mustUnderstand(1), 484 SOAP::Header->name(t2 => 7)->mustUnderstand(2), 485 ); 486 487will be serialized into: 488 489 <SOAP-ENV:Envelope ...attributes skipped> 490 <SOAP-ENV:Header> 491 <t1 xsi:type="xsd:int" SOAP-ENV:mustUnderstand="1">5</t1> 492 <t2 xsi:type="xsd:int" SOAP-ENV:mustUnderstand="1">7</t2> 493 </SOAP-ENV:Header> 494 <SOAP-ENV:Body> 495 <namesp1:mymethod xmlns:namesp1="urn:SOAP__Serializer"> 496 <c-gensym6 xsi:type="xsd:int">1</c-gensym6> 497 </namesp1:mymethod> 498 </SOAP-ENV:Body> 499 </SOAP-ENV:Envelope> 500 501You can mix C<SOAP::Header> parameters with other parameters and you can also 502return C<SOAP::Header> parameters as a result of a remote call. They will be 503placed into the header. See C<My::Parameters::addheader> as an example. 504 505=item on_action() 506 507This lets you specify a handler for C<on_action event>. It is triggered when 508creating SOAPAction. The default handler will set SOAPAction to 509C<"uri#method">. You can change this behavior globally 510(see L</"DEFAULT SETTINGS">) or locally, for a particular object. 511 512=item on_fault() 513 514This lets you specify a handler for C<on_fault> event. The default behavior is 515to B<die> on an transport error and to B<do nothing> on other error conditions. You 516may change this behavior globally (see L</"DEFAULT SETTINGS">) or locally, for a 517particular object. 518 519=item on_debug() 520 521This lets you specify a handler for C<on_debug event>. Default behavior is to 522do nothing. Use C<+trace/+debug> option for SOAP::Lite instead. If you use if 523be warned that since this method is just interface to C<+trace/+debug> it has 524B<global> effect, so if you install it for one object it'll be in effect for 525all subsequent calls (even for other objects). 526 527See also: L<SOAP::Trace>; 528 529=item on_nonserialized() 530 531This lets you specify a handler for C<on_nonserialized event>. The default 532behavior is to produce a warning if warnings are on for everything that cannot 533be properly serialized (like CODE references or GLOBs). 534 535=item call() 536 537Provides alternative interface for remote method calls. You can always 538run C<< SOAP::Lite->new(...)->method(@parameters) >>, but call() gives 539you several additional options: 540 541=over 542 543=item prefixed method 544 545If you want to specify prefix for generated method's element one of the 546available options is do it with call() interface: 547 548 print SOAP::Lite 549 -> new(....) 550 -> call('myprefix:method' => @parameters) 551 -> result; 552 553This example will work on client side only. If you want to change prefix 554on server side you should override default serializer. See 555F<examples/server/soap.*> for examples. 556 557=item access to any method 558 559If for some reason you want to get access to remote procedures that have 560the same name as methods of SOAP::Lite object these calls (obviously) won't 561be dispatched. In that case you can originate your call trough call(): 562 563 print SOAP::Lite 564 -> new(....) 565 -> call(new => @parameters) 566 -> result; 567 568=item implementation of OO interface 569 570With L<autodispatch|/"AUTODISPATCHING AND SOAP:: PREFIX"> you can make CLASS/OBJECT calls like: 571 572 my $obj = CLASS->new(@parameters); 573 print $obj->method; 574 575However, because of side effects L<autodispatch|/"AUTODISPATCHING AND SOAP:: PREFIX"> 576has, it's not always possible to use this syntax. call() provides you with 577alternative: 578 579 # you should specify uri() 580 my $soap = SOAP::Lite 581 -> uri('http://my.own.site/CLASS') # <<< CLASS goes here 582 # ..... other parameters 583 ; 584 585 my $obj = $soap->call(new => @parameters)->result; 586 print $soap->call(method => $obj)->result; 587 # $obj object will be updated here if necessary, 588 # as if you call $obj->method() and method() updates $obj 589 590 # Update of modified object MAY not work if server on another side 591 # is not SOAP::Lite 592 593=item ability to set method's attributes 594 595Additionally this syntax lets you specify attributes for method element: 596 597 print SOAP::Lite 598 -> new(....) 599 -> call(SOAP::Data->name('method')->attr({xmlns => 'mynamespace'}) 600 => @parameters) 601 -> result; 602 603You can specify B<any> attibutes and C<name> of C<SOAP::Data> element becomes 604name of method. Everything else except attributes is ignored and parameters 605should be provided as usual. 606 607Be warned, that though you have more control using this method, you B<should> 608specify namespace attribute for method explicitely, even if you made uri() 609call earlier. So, if you have to have namespace on method element, instead of: 610 611 print SOAP::Lite 612 -> new(....) 613 -> uri('mynamespace') # will be ignored 614 -> call(SOAP::Data->name('method') => @parameters) 615 -> result; 616 617do 618 619 print SOAP::Lite 620 -> new(....) 621 -> call(SOAP::Data->name('method')->attr({xmlns => 'mynamespace'}) 622 => @parameters) 623 -> result; 624 625because in the former call uri() will be ignored and namespace won't be 626specified. If you run script with C<-w> option (as recommended) SOAP::Lite 627gives you a warning: 628 629 URI is not provided as attribute for method (method) 630 631Moreover, it'll become fatal error if you try to call it with prefixed name: 632 633 print SOAP::Lite 634 -> new(....) 635 -> uri('mynamespace') # will be ignored 636 -> call(SOAP::Data->name('a:method') => @parameters) 637 -> result; 638 639gives you: 640 641 Can't find namespace for method (a:method) 642 643because nothing is associated with prefix C<'a'>. 644 645=back 646 647One more comment. One case when SOAP::Lite will change something that 648you specified is when you specified prefixed name and empty namespace name: 649 650 print SOAP::Lite 651 -> new(....) 652 -> uri('') 653 -> call('a:method' => @parameters) 654 -> result; 655 656This code will generate: 657 658 <method xmlns="">....</method> 659 660instead of 661 662 <a:method xmlns:a="">....</method> 663 664because later is not allowed according to XML Namespace specification. 665 666In all other aspects C<< ->call(mymethod => @parameters) >> is just a 667synonim for C<< ->mymethod(@parameters) >>. 668 669=item self() 670 671Returns object reference to B<global> defaul object specified with 672C<use SOAP::Lite ...> interface. Both class method and object method return 673reference to B<global> object, so: 674 675 use SOAP::Lite 676 proxy => 'http://my.global.server' 677 ; 678 679 my $soap = SOAP::Lite->proxy('http://my.local.server'); 680 681 print $soap->self->proxy; 682 683prints C<'http://my.global.server'> (the same as C<< SOAP::Lite->self->proxy >>). 684See L</"DEFAULT SETTINGS"> for more information. 685 686=item dispatch_from() 687 688Does exactly the same as L<autodispatch|/"AUTODISPATCHING AND SOAP:: PREFIX"> 689does, but doesn't install UNIVERSAL::AUTOLOAD handler and only install 690AUTOLOAD handlers in specified classes. Can be used only with C<use SOAP::Lite ...> 691clause and should be specified first: 692 693 use SOAP::Lite 694 dispatch_from => ['A', 'B'], # use "dispatch_from => 'A'" for one class 695 uri => ...., 696 proxy => ...., 697 ; 698 699 A->a; 700 B->b; 701 702=back 703 704=head2 SOAP::Header 705 706The SOAP::Header class is a subclass of the L</"SOAP::Data"> class. It is used 707in the same way as a SOAP::Data object, however SOAP::Lite will serialize 708objects of this type into the SOAP Envelope's Header block. 709 710=head2 SOAP::Data 711 712You can use this class if you want to specify a value, a name, atype, a uri or 713attributes for SOAP elements (use C<value()>, C<name()>, C<type()>, 714C<uri()> and C<attr()> methods correspondingly). 715For example, C<< SOAP::Data->name('abc')->value(123) >> will be serialized 716into C<< <abc>123</abc> >>, as well as will C<< SOAP::Data->name(abc => 123) >>. 717Each of them (except the value() method) can accept a value as the second 718parameter. All methods return the current value if you call them without 719parameters. The return the object otherwise, so you can stack them. See tests 720for more examples. You can import these methods with: 721 722 SOAP::Data->import('name'); 723 724or 725 726 import SOAP::Data 'name'; 727 728and then use C<< name(abc => 123) >> for brevity. 729 730An interface for specific attributes is also provided. You can use the C<actor()>, 731C<mustUnderstand()>, C<encodingStyle()> and C<root()> methods to set/get 732values of the correspondent attributes. 733 734 SOAP::Data 735 ->name(c => 3) 736 ->encodingStyle('http://xml.apache.org/xml-soap/literalxml') 737 738will be serialized into: 739 740 <c SOAP-ENV:encodingStyle="http://xml.apache.org/xml-soap/literalxml" 741 xsi:type="xsd:int">3</c> 742 743=head2 SOAP::Serializer 744 745Usually you don't need to interact directly with this module. The only 746case when you need it, it when using autotyping. This feature lets you specify 747types for your data according to your needs as well as to introduce new 748data types (like ordered hash for example). 749 750You can specify a type with C<< SOAP::Data->type(float => 123) >>. During 751the serialization stage the module will try to serialize your data with the 752C<as_float> method. It then calls the C<typecast> method (you can override it 753or inherit your own class from L</"SOAP::Data">) and only then it will try to 754serialize it according to data type (C<SCALAR>, C<ARRAY> or C<HASH>). For example: 755 756 SOAP::Data->type('ordered_hash' => [a => 1, b => 2]) 757 758will be serialized as an ordered hash, using the C<as_ordered_hash> method. 759 760If you do not specify a type directly, the serialization module will try 761to autodefine the type for you according to the C<typelookup> hash. It contains 762the type name as key and the following 3-element array as value: 763 764 priority, 765 check_function (CODE reference), 766 typecast function (METHOD name or CODE reference) 767 768For example, if you want to add C<uriReference> to autodefined types, 769you should add something like this: 770 771 $s->typelookup->{uriReference} = 772 [11, sub { $_[0] =~ m!^http://! }, 'as_uriReference']; 773 774and add the C<as_uriReference> method to the L</"SOAP::Serializer"> class: 775 776 sub SOAP::Serializer::as_uriReference { 777 my $self = shift; 778 my($value, $name, $type, $attr) = @_; 779 return [$name, {'xsi:type' => 'xsd:uriReference', %$attr}, $value]; 780 } 781 782The specified methods will work for both autotyping and direct typing, so you 783can use either 784 785 SOAP::Data->type(uriReference => 'http://yahoo.com')> 786 787or just 788 789 'http://yahoo.com' 790 791and it will be serialized into the same type. For more examples see C<as_*> 792methods in L</"SOAP::Serializer">. 793 794The SOAP::Serializer provides you with C<autotype()>, C<readable()>, C<namespace()>, 795C<encodingspace()>, C<encoding()>, C<typelookup()>, C<uri()>, C<multirefinplace()> and 796C<envelope()> methods. All methods (except C<envelope()>) are described in the 797L</"SOAP::Lite"> section. 798 799=over 4 800 801=item envelope() 802 803This method allows you to build three kind of envelopes depending on the first 804parameter: 805 806=over 4 807 808=item method 809 810 envelope(method => 'methodname', @parameters); 811 812or 813 814 method('methodname', @parameters); 815 816Lets you build a request/response envelope. 817 818=item fault 819 820 envelope(fault => 'faultcode', 'faultstring', $details); 821 822or 823 824 fault('faultcode', 'faultstring', $details); 825 826Lets you build a fault envelope. Faultcode will be properly qualified and 827details could be string or object. 828 829=item freeform 830 831 envelope(freeform => 'something that I want to serialize'); 832 833or 834 835 freeform('something that I want to serialize'); 836 837Reserved for nonRPC calls. Lets you build your own payload inside a SOAP 838envelope. All SOAP 1.1 specification rules are enforced, except method 839specific ones. See UDDI::Lite as example. 840 841=item register_ns 842 843The register_ns subroutine allows users to register a global namespace 844with the SOAP Envelope. The first parameter is the namespace, the second 845parameter to this subroutine is an optional prefix. If a prefix is not 846provided, one will be generated automatically for you. All namespaces 847registered with the serializer get declared in the <soap:Envelope /> 848element. 849 850=item find_prefix 851 852The find_prefix subroutine takes a namespace as a parameter and returns 853the assigned prefix to that namespace. This eliminates the need to declare 854and redeclare namespaces within an envelope. This subroutine is especially 855helpful in determining the proper prefix when assigning a type to a 856SOAP::Data element. A good example of how this might be used is as follows: 857 858SOAP::Data->name("foo" => $inputParams{'foo'}) 859 ->type($client->serializer->find_prefix('urn:Foo').':Foo'); 860 861=item xmlschema 862 863The xmlschema subroutine tells SOAP::Lite what XML Schema to use when 864serializing XML element values. There are two supported schemas of 865SOAP::Lite, they are: 866 867 http://www.w3.org/1999/XMLSchema, and 868 http://www.w3.org/2001/XMLSchema (default) 869 870=back 871 872=back 873 874For more examples see tests and SOAP::Transport::HTTP.pm 875 876=head2 SOAP::SOM 877 878All calls you are making through object oriented interface will 879return SOAP::SOM object, and you can access actual values with it. 880Next example gives you brief overview of the class: 881 882 my $soap = SOAP::Lite .....; 883 my $som = $soap->method(@parameters); 884 885 if ($som->fault) { # will be defined if Fault element is in the message 886 print $som->faultdetail; # returns value of 'detail' element as 887 # string or object 888 $som->faultcode; # 889 $som->faultstring; # also available 890 $som->faultactor; # 891 } else { 892 $som->result; # gives you access to result of call 893 # it could be any data structure, for example reference 894 # to array if server didi something like: return [1,2]; 895 896 $som->paramsout; # gives you access to out parameters if any 897 # for example, you'll get array (1,2) if 898 # server returns ([1,2], 1, 2); 899 # [1,2] will be returned as $som->result 900 # and $som->paramsall will return ([1,2], 1, 2) 901 # see section IN/OUT, OUT PARAMETERS AND AUTOBINDING 902 # for more information 903 904 $som->paramsall; # gives access to result AND out parameters (if any) 905 # and returns them as one array 906 907 $som->valueof('//myelement'); # returns value(s) (as perl data) of 908 # 'myelement' if any. All elements in array 909 # context and only first one in scalar 910 911 $h = $som->headerof('//myheader'); # returns element as SOAP::Header, so 912 # you can access attributes and values 913 # with $h->mustUnderstand, $h->actor 914 # or $h->attr (for all attributes) 915 } 916 917SOAP::SOM object gives you access to the deserialized envelope via several 918methods. All methods accept a node path (similar to XPath notations). 919SOM interprets '/' as the root node, '//' as relative location path 920('//Body' will find all bodies in document, as well as 921'/Envelope//nums' will find all 'nums' nodes under Envelope node), 922'[num]' as node number and '[op num]' with C<op> being a comparison 923operator ('<', '>', '<=', '>=', '!', '='). 924 925All nodes in nodeset will be returned in document order. 926 927=over 4 928 929=item match() 930 931Accepts a path to a node and returns true/false in a boolean context and 932a SOM object otherwise. C<valueof()> and C<dataof()> can be used to get 933value(s) of matched node(s). 934 935=item valueof() 936 937Returns the value of a (previously) matched node. It accepts a node path. 938In this case, it returns the value of matched node, but does not change the current 939node. Suitable when you want to match a node and then navigate through 940node children: 941 942 $som->match('/Envelope/Body/[1]'); # match method 943 $som->valueof('[1]'); # result 944 $som->valueof('[2]'); # first out parameter (if present) 945 946The returned value depends on the context. In a scalar context it will return 947the first element from matched nodeset. In an array context it will return 948all matched elements. 949 950=item dataof() 951 952Same as C<valueof()>, but it returns a L</"SOAP::Data"> object, so you can get 953access to the name, the type and attributes of an element. 954 955=item headerof() 956 957Same as C<dataof()>, but it returns L</"SOAP::Header"> object, so you can get 958access to the name, the type and attributes of an element. Can be used for 959modifying headers (if you want to see updated header inside Header element, 960it's better to use this method instead of C<dataof()> method). 961 962=item namespaceuriof() 963 964Returns the uri associated with the matched element. This uri can also be 965inherited, for example, if you have 966 967 <a xmlns='http://my.namespace'> 968 <b> 969 value 970 </b> 971 </a> 972 973this method will return same value for 'b' element as for 'a'. 974 975=back 976 977SOAP::SOM also provides methods for direct access to the envelope, the body, 978methods and parameters (both in and out). All these methods return real 979values (in most cases it will be a hash reference), if called as object 980method. Returned values also depend on context: in an array context it will 981return an array of values and in scalar context it will return the first 982element. So, if you want to access the first output parameter, you can call 983C<< $param = $som->paramsout >>; 984and you will get it regardless of the actual number of output parameters. 985If you call it as class function (for example, SOAP::SOM::method) 986it returns an XPath string that matches the current element 987('/Envelope/Body/[1]' in case of 'method'). The method will return C<undef> 988if not present OR if you try to access an undefined element. To distinguish 989between these two cases you can first access the C<match()> method that 990will return true/false in a boolean context and then get the real value: 991 992 if ($som->match('//myparameter')) { 993 $value = $som->valueof; # can be undef too 994 } else { 995 # doesn't exist 996 } 997 998=over 4 999 1000=item root() 1001 1002Returns the value (as hash) of the root element. Do exactly the same as 1003C<< $som->valueof('/') >> does. 1004 1005=item envelope() 1006 1007Returns the value (as hash) of the C<Envelope> element. Keys in this hash will be 1008'Header' (if present), 'Body' and any other (optional) elements. Values will 1009be the deserialized header, body, and elements, respectively. 1010If called as function (C<SOAP::SOM::envelope>) it will return a Xpath string 1011that matches the envelope content. Useful when you want just match it and 1012then iterate over the content by yourself. Example: 1013 1014 if ($som->match(SOAP::SOM::envelope)) { 1015 $som->valueof('Header'); # should give access to header if present 1016 $som->valueof('Body'); # should give access to body 1017 } else { 1018 # hm, are we doing SOAP or what? 1019 } 1020 1021=item header() 1022 1023Returns the value (as hash) of the C<Header> element. If you want to access all 1024attributes in the header use: 1025 1026 # get element as SOAP::Data object 1027 $transaction = $som->match(join '/', SOAP::SOM::header, 'transaction')->dataof; 1028 # then you can access all attributes of 'transaction' element 1029 $transaction->attr; 1030 1031=item headers() 1032 1033Returns a node set of values with deserialized headers. The difference between 1034the C<header()> and C<headers()> methods is that the first gives you access 1035to the whole header and second to the headers inside the 'Header' tag: 1036 1037 $som->headerof(join '/', SOAP::SOM::header, '[1]'); 1038 # gives you first header as SOAP::Header object 1039 1040 ($som->headers)[0]; 1041 # gives you value of the first header, same as 1042 $som->valueof(join '/', SOAP::SOM::header, '[1]'); 1043 1044 $som->header->{name_of_your_header_here} 1045 # gives you value of name_of_your_header_here 1046 1047=item body() 1048 1049Returns the value (as hash) of the C<Body> element. 1050 1051=item fault() 1052 1053Returns the value (as hash) of C<Fault> element: C<faultcode>, C<faultstring> and 1054C<detail>. If C<Fault> element is present, C<result()>, C<paramsin()>, 1055C<paramsout()> and C<method()> will return an undef. 1056 1057=item faultcode() 1058 1059Returns the value of the C<faultcode> element if present and undef otherwise. 1060 1061=item faultstring() 1062 1063Returns the value of the C<faultstring> element if present and undef otherwise. 1064 1065=item faultactor() 1066 1067Returns the value of the C<faultactor> element if present and undef otherwise. 1068 1069=item faultdetail() 1070 1071Returns the value of the C<detail> element if present and undef otherwise. 1072 1073=item method() 1074 1075Returns the value of the method element (all input parameters if you call it on 1076a deserialized request envelope, and result/output parameters if you call it 1077on a deserialized response envelope). Returns undef if the 'Fault' element is 1078present. 1079 1080=item result() 1081 1082Returns the value of the C<result> of the method call. In fact, it will return 1083the first child element (in document order) of the method element. 1084 1085=item paramsin() 1086 1087Returns the value(s) of all passed parameters. 1088 1089=item paramsout() 1090 1091Returns value(s) of the output parameters. 1092 1093=item paramsall() 1094 1095Returns value(s) of the result AND output parameters as one array. 1096 1097=item parts() 1098 1099Return an array of MIME::Entities if the current payload contains attachments, or returns undefined if payload is not MIME multipart. 1100 1101=item is_multipart() 1102 1103Returns true if payload is MIME multipart, false otherwise. 1104 1105=back 1106 1107=head2 SOAP::Schema 1108 1109SOAP::Schema gives you ability to load schemas and create stubs according 1110to these schemas. Different syntaxes are provided: 1111 1112=over 4 1113 1114=item * 1115 1116 use SOAP::Lite 1117 service => 'http://www.xmethods.net/sd/StockQuoteService.wsdl', 1118 # service => 'file:/your/local/path/StockQuoteService.wsdl', 1119 # service => 'file:./StockQuoteService.wsdl', 1120 ; 1121 print getQuote('MSFT'), "\n"; 1122 1123=item * 1124 1125 use SOAP::Lite; 1126 print SOAP::Lite 1127 -> service('http://www.xmethods.net/sd/StockQuoteService.wsdl') 1128 -> getQuote('MSFT'), "\n"; 1129 1130=item * 1131 1132 use SOAP::Lite; 1133 my $service = SOAP::Lite 1134 -> service('http://www.xmethods.net/sd/StockQuoteService.wsdl'); 1135 print $service->getQuote('MSFT'), "\n"; 1136 1137=back 1138 1139You can create stub with B<stubmaker> script: 1140 1141 perl stubmaker.pl http://www.xmethods.net/sd/StockQuoteService.wsdl 1142 1143and you'll be able to access SOAP services in one line: 1144 1145 perl "-MStockQuoteService qw(:all)" -le "print getQuote('MSFT')" 1146 1147or dynamically: 1148 1149 perl "-MSOAP::Lite service=>'file:./quote.wsdl'" -le "print getQuote('MSFT')" 1150 1151Other supported syntaxes with stub(s) are: 1152 1153=over 4 1154 1155=item * 1156 1157 use StockQuoteService ':all'; 1158 print getQuote('MSFT'), "\n"; 1159 1160=item * 1161 1162 use StockQuoteService; 1163 print StockQuoteService->getQuote('MSFT'), "\n"; 1164 1165=item * 1166 1167 use StockQuoteService; 1168 my $service = StockQuoteService->new; 1169 print $service->getQuote('MSFT'), "\n"; 1170 1171=back 1172 1173Support for schemas is limited for now. Though module was tested with dozen 1174different schemas it won't understand complex objects and will work only 1175with WSDL. 1176 1177=head2 SOAP::Trace 1178 1179SOAP::Trace provides you with a trace/debug facility for the SOAP::Lite 1180library. To activate it you need to specify a list of traceable 1181events/parts of SOAP::Lite: 1182 1183 use SOAP::Lite +trace => 1184 [qw(list of available traces here)]; 1185 1186Available events are: 1187 1188 transport -- (client) access to request/response for transport layer 1189 dispatch -- (server) shows full name of dispatched call 1190 result -- (server) result of method call 1191 parameters -- (server) parameters for method call 1192 headers -- (server) headers of received message 1193 objects -- (both) new/DESTROY calls 1194 method -- (both) parameters for '->envelope(method =>' call 1195 fault -- (both) parameters for '->envelope(fault =>' call 1196 freeform -- (both) parameters for '->envelope(freeform =>' call 1197 trace -- (both) trace enters into some important functions 1198 debug -- (both) details about transport 1199 1200For example: 1201 1202 use SOAP::Lite +trace => 1203 [qw(method fault)]; 1204 1205lets you output the parameter values for all your fault/normal envelopes onto STDERR. 1206If you want to log it you can either redirect STDERR to some file 1207 1208 BEGIN { open(STDERR, '>>....'); } 1209 1210or (preferably) define your own function for a particular event: 1211 1212 use SOAP::Lite +trace => 1213 [ method => sub {'log messages here'}, fault => \&log_faults ]; 1214 1215You can share the same function for several events: 1216 1217 use SOAP::Lite +trace => 1218 [method, fault => \&log_methods_and_faults]; 1219 1220Also you can use 'all' to get all available tracing and use '-' in front of an event to disable particular event: 1221 1222 use SOAP::Lite +trace => 1223 [ all, -transport ]; # to get all logging without transport messages 1224 1225Finally, 1226 1227 use SOAP::Lite +trace; 1228 1229will switch all debugging on. 1230 1231You can use 'debug' instead of 'trace'. I prefer 'trace', others 'debug'. 1232Also C<on_debug> is available for backward compatibility, as in 1233 1234 use SOAP::Lite; 1235 1236 my $s = SOAP::Lite 1237 -> uri('http://tempuri.org/') 1238 -> proxy('http://beta.search.microsoft.com/search/MSComSearchService.asmx') 1239 -> on_debug(sub{print@_}) # show you request/response with headers 1240 ; 1241 print $s->GetVocabulary(SOAP::Data->name(Query => 'something')->uri('http://tempuri.org/')) 1242 ->valueof('//FOUND'); 1243 1244or switch it on individually, with 1245 1246 use SOAP::Lite +trace => debug; 1247 1248or 1249 1250 use SOAP::Lite +trace => [debug => sub {'do_what_I_want_here'}]; 1251 1252Compare this with: 1253 1254 use SOAP::Lite +trace => transport; 1255 1256which gives you access to B<actual> request/response objects, so you can even 1257set/read cookies or do whatever you want there. 1258 1259The difference between C<debug> and C<transport> is that C<transport> will get 1260a HTTP::Request/HTTP::Response object and C<debug> will get a stringified request 1261(NOT OBJECT!). It can also be called in other places too. 1262 1263=head2 SOAP::Transport 1264 1265Supports the SOAP Transport architecture. All transports must extend this 1266class. 1267 1268=head2 SOAP::Fault 1269 1270This class gives you access to Fault generated on server side. To make a 1271Fault message you might simply die on server side and SOAP processor will 1272wrap you message as faultstring element and will transfer Fault on client 1273side. But in some cases you need to have more control over this process and 1274SOAP::Fault class gives it to you. To use it, simply die with SOAP::Fault 1275object as a parameter: 1276 1277 die SOAP::Fault->faultcode('Server.Custom') # will be qualified 1278 ->faultstring('Died in server method') 1279 ->faultdetail(bless {code => 1} => 'BadError') 1280 ->faultactor('http://www.soaplite.com/custom'); 1281 1282faultdetail() and faultactor() methods are optional and since faultcode and 1283faultstring are required to represent fault message SOAP::Lite will use 1284default values ('Server' and 'Application error') if not specified. 1285 1286=head2 SOAP::Utils 1287 1288This class gives you access to a number of subroutines to assist in data 1289formating, encoding, etc. Many of the subroutines are private, and are not 1290documented here, but a few are made public. They are: 1291 1292=over 4 1293 1294=item format_datetime 1295 1296 Returns a valid xsd:datetime string given a time object returned by 1297 Perl's localtime function. Usage: 1298 1299 print SOAP::Utils::format_datetime(localtime); 1300 1301=back 1302 1303=head2 SOAP::Constants 1304 1305This class gives you access to number of options that may affect behavior of 1306SOAP::Lite objects. They are not true contstants, aren't they? 1307 1308=over 1309 1310=item $PATCH_HTTP_KEEPALIVE 1311 1312SOAP::Lite's HTTP Transport module attempts to provide a simple patch to 1313LWP::Protocol to enable HTTP Keep Alive. By default, this patch is turned 1314off, if however you would like to turn on the experimental patch change the 1315constant like so: 1316 1317 $SOAP::Constants::PATCH_HTTP_KEEPALIVE = 1; 1318 1319=item $DO_NOT_USE_XML_PARSER 1320 1321By default SOAP::Lite tries to load XML::Parser and if it fails, then to 1322load XML::Parser::Lite. You may skip the first step and use XML::Parser::Lite 1323even if XML::Parser is presented in your system if assign true value like this: 1324 1325 $SOAP::Constants::DO_NOT_USE_XML_PARSER = 1; 1326 1327=item $DO_NOT_USE_CHARSET 1328 1329By default SOAP::Lite specifies charset in content-type. Since not every 1330toolkit likes it you have an option to switch it off if you set 1331C<$DO_NOT_USE_CHARSET> to true. 1332 1333=item $DO_NOT_CHECK_CONTENT_TYPE 1334 1335By default SOAP::Lite verifies that content-type in successful response has 1336value 'multipart/related' or 'multipart/form-data' for MIME-encoded messages 1337and 'text/xml' for all other ocassions. SOAP::Lite will raise exception for 1338all other values. C<$DO_NOT_CHECK_CONTENT_TYPE> when set to true will allow 1339you to accept those values as valid. 1340 1341=back 1342 1343=head1 FEATURES AND OPTIONS 1344 1345=head2 DEFAULT SETTINGS 1346 1347Though this feature looks similar to L<autodispatch|/"AUTODISPATCHING AND SOAP:: PREFIX"> they have (almost) 1348nothing in common. It lets you create default object and all objects 1349created after that will be cloned from default object and hence get its 1350properties. If you want to provide common proxy() or uri() settings for 1351all SOAP::Lite objects in your application you may do: 1352 1353 use SOAP::Lite 1354 proxy => 'http://localhost/cgi-bin/soap.cgi', 1355 uri => 'http://my.own.com/My/Examples' 1356 ; 1357 1358 my $soap1 = new SOAP::Lite; # will get the same proxy()/uri() as above 1359 print $soap1->getStateName(1)->result; 1360 1361 my $soap2 = SOAP::Lite->new; # same thing as above 1362 print $soap2->getStateName(2)->result; 1363 1364 # or you may override any settings you want 1365 my $soap3 = SOAP::Lite->proxy('http://localhost/'); 1366 print $soap3->getStateName(1)->result; 1367 1368B<Any> SOAP::Lite properties can be propagated this way. Changes in object 1369copies will not affect global settings and you may still change global 1370settings with C<< SOAP::Lite->self >> call which returns reference to 1371global object. Provided parameter will update this object and you can 1372even set it to C<undef>: 1373 1374 SOAP::Lite->self(undef); 1375 1376The C<use SOAP::Lite> syntax also lets you specify default event handlers 1377for your code. If you have different SOAP objects and want to share the 1378same C<on_action()> (or C<on_fault()> for that matter) handler. You can 1379specify C<on_action()> during initialization for every object, but 1380you may also do: 1381 1382 use SOAP::Lite 1383 on_action => sub {sprintf '%s#%s', @_} 1384 ; 1385 1386and this handler will be the default handler for all your SOAP objects. 1387You can override it if you specify a handler for a particular object. 1388See F<t/*.t> for example of on_fault() handler. 1389 1390Be warned, that since C<use ...> is executed at compile time B<all> C<use> 1391statements will be executed B<before> script execution that can make 1392unexpected results. Consider code: 1393 1394 use SOAP::Lite proxy => 'http://localhost/'; 1395 1396 print SOAP::Lite->getStateName(1)->result; 1397 1398 use SOAP::Lite proxy => 'http://localhost/cgi-bin/soap.cgi'; 1399 1400 print SOAP::Lite->getStateName(1)->result; 1401 1402B<BOTH> SOAP calls will go to C<'http://localhost/cgi-bin/soap.cgi'>. If 1403you want to execute C<use> at run-time, put it in C<eval>: 1404 1405 eval "use SOAP::Lite proxy => 'http://localhost/cgi-bin/soap.cgi'; 1" or die; 1406 1407or use 1408 1409 SOAP::Lite->self->proxy('http://localhost/cgi-bin/soap.cgi'); 1410 1411=head2 IN/OUT, OUT PARAMETERS AND AUTOBINDING 1412 1413SOAP::Lite gives you access to all parameters (both in/out and out) and 1414also does some additional work for you. Lets consider following example: 1415 1416 <mehodResponse> 1417 <res1>name1</res1> 1418 <res2>name2</res2> 1419 <res3>name3</res3> 1420 </mehodResponse> 1421 1422In that case: 1423 1424 $result = $r->result; # gives you 'name1' 1425 $paramout1 = $r->paramsout; # gives you 'name2', because of scalar context 1426 $paramout1 = ($r->paramsout)[0]; # gives you 'name2' also 1427 $paramout2 = ($r->paramsout)[1]; # gives you 'name3' 1428 1429or 1430 1431 @paramsout = $r->paramsout; # gives you ARRAY of out parameters 1432 $paramout1 = $paramsout[0]; # gives you 'res2', same as ($r->paramsout)[0] 1433 $paramout2 = $paramsout[1]; # gives you 'res3', same as ($r->paramsout)[1] 1434 1435Generally, if server returns C<return (1,2,3)> you will get C<1> as the result 1436and C<2> and C<3> as out parameters. 1437 1438If the server returns C<return [1,2,3]> you will get an ARRAY from C<result()> and 1439C<undef> from C<paramsout()> . 1440Results can be arbitrary complex: they can be an array of something, they can 1441be objects, they can be anything and still be returned by C<result()> . If only 1442one parameter is returned, C<paramsout()> will return C<undef>. 1443 1444But there is more. 1445If you have in your output parameters a parameter with the same 1446signature (name+type) as in the input parameters this parameter will be mapped 1447into your input automatically. Example: 1448 1449B<server>: 1450 1451 sub mymethod { 1452 shift; # object/class reference 1453 my $param1 = shift; 1454 my $param2 = SOAP::Data->name('myparam' => shift() * 2); 1455 return $param1, $param2; 1456 } 1457 1458B<client>: 1459 1460 $a = 10; 1461 $b = SOAP::Data->name('myparam' => 12); 1462 $result = $soap->mymethod($a, $b); 1463 1464After that, C<< $result == 10 and $b->value == 24 >>! Magic? Sort of. 1465Autobinding gives it to you. That will work with objects also with 1466one difference: you do not need to worry about the name and the type of 1467object parameter. Consider the C<PingPong> example (F<examples/My/PingPong.pm> and 1468F<examples/pingpong.pl>): 1469 1470B<server>: 1471 1472 package My::PingPong; 1473 1474 sub new { 1475 my $self = shift; 1476 my $class = ref($self) || $self; 1477 bless {_num=>shift} => $class; 1478 } 1479 1480 sub next { 1481 my $self = shift; 1482 $self->{_num}++; 1483 } 1484 1485B<client>: 1486 1487 use SOAP::Lite +autodispatch => 1488 uri => 'urn:', 1489 proxy => 'http://localhost/' 1490 ; 1491 1492 my $p = My::PingPong->new(10); # $p->{_num} is 10 now, real object returned 1493 print $p->next, "\n"; # $p->{_num} is 11 now!, object autobinded 1494 1495=head2 AUTODISPATCHING AND SOAP:: PREFIX 1496 1497B<WARNING>: C<autodispatch> feature can have side effects for your application 1498and can affect functionality of other modules/libraries because of overloading 1499UNIVERSAL::AUTOLOAD. All unresolved calls will be dispatched as SOAP calls, 1500however it could be not what you want in some cases. If so, consider using 1501object interface (see C<implementation of OO interface>). 1502 1503SOAP::Lite provides an autodispatching feature that lets you create 1504code which looks the same for local and remote access. 1505 1506For example: 1507 1508 use SOAP::Lite +autodispatch => 1509 uri => 'urn:/My/Examples', 1510 proxy => 'http://localhost/' 1511 ; 1512 1513tells SOAP to 'autodispatch' all calls to the 'http://localhost/' endpoint with 1514the 'urn:/My/Examples' uri. All consequent method calls can look like: 1515 1516 print getStateName(1), "\n"; 1517 print getStateNames(12,24,26,13), "\n"; 1518 print getStateList([11,12,13,42])->[0], "\n"; 1519 print getStateStruct({item1 => 10, item2 => 4})->{item2}, "\n"; 1520 1521As you can see, there is no SOAP specific coding at all. 1522 1523The same logic will work for objects as well: 1524 1525 print "Session iterator\n"; 1526 my $p = My::SessionIterator->new(10); 1527 print $p->next, "\n"; 1528 print $p->next, "\n"; 1529 1530This will access the remote My::SessionIterator module, gets an object, and then 1531calls remote methods again. The object will be transferred to the server, the 1532method is executed there and the result (and the modified object!) will be 1533transferred back to the client. 1534 1535Autodispatch will work B<only> if you do not have the same method in your 1536code. For example, if you have C<use My::SessionIterator> somewhere in your 1537code of our previous example, all methods will be resolved locally and no 1538SOAP calls will be done. If you want to get access to remote objects/methods 1539even in that case, use C<SOAP::> prefix to your methods, like: 1540 1541 print $p->SOAP::next, "\n"; 1542 1543See C<pingpong.pl> for example of a script, that works with the same object 1544locally and remotely. 1545 1546C<SOAP::> prefix also gives you ability to access methods that have the same 1547name as methods of SOAP::Lite itself. For example, you want to call method 1548new() for your class C<My::PingPong> through OO interface. 1549First attempt could be: 1550 1551 my $s = SOAP::Lite 1552 -> uri('http://www.soaplite.com/My/PingPong') 1553 -> proxy('http://localhost/cgi-bin/soap.cgi') 1554 ; 1555 my $obj = $s->new(10); 1556 1557but it won't work, because SOAP::Lite has method new() itself. To provide 1558a hint, you should use C<SOAP::> prefix and call will be dispatched remotely: 1559 1560 my $obj = $s->SOAP::new(10); 1561 1562You can mix autodispatch and usual SOAP calls in the same code if 1563you need it. Keep in mind, that calls with SOAP:: prefix should always be a 1564method call, so if you want to call functions, use C<< SOAP->myfunction() >> 1565instead of C<SOAP::myfunction()>. 1566 1567Be warned though Perl has very flexible syntax some versions will complain 1568 1569 Bareword "autodispatch" not allowed while "strict subs" in use ... 1570 1571if you try to put 'autodispatch' and '=>' on separate lines. So, keep them 1572on the same line, or put 'autodispatch' in quotes: 1573 1574 use SOAP::Lite 'autodispatch' # DON'T use plus in this case 1575 => .... 1576 ; 1577 1578=head2 ACCESSING HEADERS AND ENVELOPE ON SERVER SIDE 1579 1580SOAP::Lite gives you direct access to all headers and the whole envelope on 1581the server side. Consider the following code from My::Parameters.pm: 1582 1583 sub byname { 1584 my($a, $b, $c) = @{pop->method}{qw(a b c)}; 1585 return "a=$a, b=$b, c=$c"; 1586 } 1587 1588You will get this functionality ONLY if you inherit your class from 1589the SOAP::Server::Parameters class. This should keep existing code working and 1590provides this feature only when you need it. 1591 1592Every method on server side will be called as class/object method, so it will 1593get an B<object reference> or a B<class name> as the first parameter, then the 1594method parameters, and then an envelope as SOAP::SOM object. Shortly: 1595 1596 $self [, @parameters] , $envelope 1597 1598If you have a fixed number of parameters, you can do: 1599 1600 my $self = shift; 1601 my($param1, $param2) = @_; 1602 1603and ignore the envelope. If you need access to the envelope you can do: 1604 1605 my $envelope = pop; 1606 1607since the envelope is always the last element in the parameters list. 1608The C<byname()> method C<< pop->method >> will return a hash with 1609parameter names as hash keys and parameter values as hash values: 1610 1611 my($a, $b, $c) = @{pop->method}{qw(a b c)}; 1612 1613gives you by-name access to your parameters. 1614 1615=head2 SERVICE DEPLOYMENT. STATIC AND DYNAMIC 1616 1617Let us scrutinize the deployment process. When designing your SOAP server you 1618can consider two kind of deployment: B<static> and B<dynamic>. 1619For both, static and dynamic, you should specify C<MODULE>, 1620C<MODULE::method>, C<method> or C<PATH/> when creating C<use>ing the 1621SOAP::Lite module. The difference between static and dynamic deployment is 1622that in case of 'dynamic', any module which is not present will be loaded on 1623demand. See the L</"SECURITY"> section for detailed description. 1624 1625Example for B<static> deployment: 1626 1627 use SOAP::Transport::HTTP; 1628 use My::Examples; # module is preloaded 1629 1630 SOAP::Transport::HTTP::CGI 1631 # deployed module should be present here or client will get 'access denied' 1632 -> dispatch_to('My::Examples') 1633 -> handle; 1634 1635Example for B<dynamic> deployment: 1636 1637 use SOAP::Transport::HTTP; 1638 # name is unknown, module will be loaded on demand 1639 1640 SOAP::Transport::HTTP::CGI 1641 # deployed module should be present here or client will get 'access denied' 1642 -> dispatch_to('/Your/Path/To/Deployed/Modules', 'My::Examples') 1643 -> handle; 1644 1645For static deployment you should specify the MODULE name directly. 1646For dynamic deployment you can specify the name either directly (in that 1647case it will be C<require>d without any restriction) or indirectly, with a PATH 1648In that case, the ONLY path that will be available will be the PATH given 1649to the dispatch_to() method). For information how to handle this situation 1650see L</"SECURITY"> section. 1651 1652You should also use static binding when you have several different classes 1653in one file and want to make them available for SOAP calls. 1654 1655B<SUMMARY>: 1656 1657 dispatch_to( 1658 # dynamic dispatch that allows access to ALL modules in specified directory 1659 PATH/TO/MODULES 1660 # 1. specifies directory 1661 # -- AND -- 1662 # 2. gives access to ALL modules in this directory without limits 1663 1664 # static dispatch that allows access to ALL methods in particular MODULE 1665 MODULE 1666 # 1. gives access to particular module (all available methods) 1667 # PREREQUISITES: 1668 # module should be loaded manually (for example with 'use ...') 1669 # -- OR -- 1670 # you can still specify it in PATH/TO/MODULES 1671 1672 # static dispatch that allows access to particular method ONLY 1673 MODULE::method 1674 # same as MODULE, but gives access to ONLY particular method, 1675 # so there is not much sense to use both MODULE and MODULE::method 1676 # for the same MODULE 1677 ) 1678 1679In addition to this SOAP::Lite also supports experimental syntax that 1680allows you bind specific URL or SOAPAction to CLASS/MODULE or object: 1681 1682 dispatch_with({ 1683 URI => MODULE, # 'http://www.soaplite.com/' => 'My::Class', 1684 SOAPAction => MODULE, # 'http://www.soaplite.com/method' => 'Another::Class', 1685 URI => object, # 'http://www.soaplite.com/obj' => My::Class->new, 1686 }) 1687 1688URI is checked before SOAPAction. You may use both C<dispatch_to()> and 1689C<dispatch_with()> syntax and C<dispatch_with()> has more priority, so 1690first checked URI, then SOAPAction and only then will be checked 1691C<dispatch_to()>. See F<t/03-server.t> for more information and examples. 1692 1693=head2 SECURITY 1694 1695Due to security reasons, the current path for perl modules (C<@INC>) will be disabled 1696once you have chosen dynamic deployment and specified your own C<PATH/>. 1697If you want to access other modules in your included package you have 1698several options: 1699 1700=over 4 1701 1702=item 1 1703 1704Switch to static linking: 1705 1706 use MODULE; 1707 $server->dispatch_to('MODULE'); 1708 1709It can be useful also when you want to import something specific 1710from the deployed modules: 1711 1712 use MODULE qw(import_list); 1713 1714=item 2 1715 1716Change C<use> to C<require>. The path is unavailable only during 1717the initialization part, and it is available again during execution. 1718So, if you do C<require> somewhere in your package, it will work. 1719 1720=item 3 1721 1722Same thing, but you can do: 1723 1724 eval 'use MODULE qw(import_list)'; die if $@; 1725 1726=item 4 1727 1728Assign a C<@INC> directory in your package and then make C<use>. 1729Don't forget to put C<@INC> in C<BEGIN{}> block or it won't work: 1730 1731 BEGIN { @INC = qw(my_directory); use MODULE } 1732 1733=back 1734 1735=head2 COMPRESSION 1736 1737SOAP::Lite provides you option for enabling compression on wire (for HTTP 1738transport only). Both server and client should support this capability, 1739but this logic should be absolutely transparent for your application. 1740 1741Compression can be enabled by specifying threshold for compression on client 1742or server side: 1743 1744=over 4 1745 1746=item Client 1747 1748 print SOAP::Lite 1749 -> uri('http://localhost/My/Parameters') 1750 -> proxy('http://localhost/', options => {compress_threshold => 10000}) 1751 -> echo(1 x 10000) 1752 -> result 1753 ; 1754 1755=item Server 1756 1757 my $server = SOAP::Transport::HTTP::CGI 1758 -> dispatch_to('My::Parameters') 1759 -> options({compress_threshold => 10000}) 1760 -> handle; 1761 1762=back 1763 1764For more information see L<COMPRESSION section|SOAP::Transport::HTTP/"COMPRESSION"> 1765in HTTP transport documentation. 1766 1767=head2 OBJECTS-BY-REFERENCE 1768 1769SOAP::Lite implements an experimental (yet functional) support for 1770objects-by-reference. You should not see any difference on the client side 1771when using this. On the server side you should specify the names of the 1772classes you want to be returned by reference (instead of by value) in the 1773C<objects_by_reference()> method for your server implementation (see 1774soap.pop3, soap.daemon and Apache.pm). 1775 1776Garbage collection is done on the server side (not earlier than after 600 1777seconds of inactivity time), and you can overload the default behavior with 1778specific functions for any particular class. 1779 1780Binding does not have any special syntax and is implemented on server side 1781(see the differences between My::SessionIterator and My::PersistentIterator). 1782On the client side, objects will have same type/class as before 1783(C<< My::SessionIterator->new() >> will return an object of class 1784My::SessionIterator). However, this object is just a stub with an object ID 1785inside. 1786 1787=head2 INTEROPERABILITY 1788 1789=over 4 1790 1791=item Microsoft's .NET 1792 1793To use .NET client and SOAP::Lite server 1794 1795=over 4 1796 1797=item qualify all elements 1798 1799use fully qualified names for your return values, e.g.: 1800 1801 return SOAP::Data->name('myname') 1802 ->type('string') 1803 ->uri('http://tempuri.org/') 1804 ->value($output); 1805 1806Use namespace that you specify for URI instead of 'http://tempuri.org/'. 1807 1808In addition see comment about default encoding in .NET Web Services below. 1809 1810=back 1811 1812To use SOAP::Lite client and .NET server 1813 1814=over 4 1815 1816=item declare proper soapAction (uri/method) in your call 1817 1818For example, use C<on_action(sub{join '', @_})>. 1819 1820=item disable charset in content-type 1821 1822Specify C<$SOAP::Constants::DO_NOT_USE_CHARSET = 1> somewhere in your code 1823after C<use SOAP::Lite> if you are getting error: 1824 1825 Server found request content type to be 'text/xml; charset=utf-8', 1826 but expected 'text/xml' 1827 1828=item qualify all elements 1829 1830Any of following actions should work: 1831 1832=over 4 1833 1834=item use fully qualified name for method parameters 1835 1836Use C<< SOAP::Data->name(Query => 'biztalk')->uri('http://tempuri.org/') >> instead of 1837C<< SOAP::Data->name('Query' => 'biztalk') >>. 1838 1839Example of SOAPsh call (all parameters should be in one line): 1840 1841 > perl SOAPsh.pl 1842 "http://beta.search.microsoft.com/search/mscomsearchservice.asmx" 1843 "http://tempuri.org/" 1844 "on_action(sub{join '', @_})" 1845 "GetVocabulary(SOAP::Data->name(Query => 'biztalk')->uri('http://tempuri.org/'))" 1846 1847=item make method in default namespace 1848 1849instead of 1850 1851 my @rc = $soap->call(add => @parms)->result; 1852 # -- OR -- 1853 my @rc = $soap->add(@parms)->result; 1854 1855use 1856 1857 my $method = SOAP::Data->name('add') 1858 ->attr({xmlns => 'http://tempuri.org/'}); 1859 my @rc = $soap->call($method => @parms)->result; 1860 1861=item modify .NET server if you are in charge for that 1862 1863Stefan Pharies <stefanph@microsoft.com>: 1864 1865SOAP::Lite uses the SOAP encoding (section 5 of the soap 1.1 spec), and 1866the default for .NET Web Services is to use a literal encoding. So 1867elements in the request are unqualified, but your service expects them to 1868be qualified. .Net Web Services has a way for you to change the expected 1869message format, which should allow you to get your interop working. 1870At the top of your class in the asmx, add this attribute (for Beta 1): 1871 1872 [SoapService(Style=SoapServiceStyle.RPC)] 1873 1874Another source said it might be this attribute (for Beta 2): 1875 1876 [SoapRpcService] 1877 1878Full Web Service text may look like: 1879 1880 <%@ WebService Language="C#" Class="Test" %> 1881 using System; 1882 using System.Web.Services; 1883 using System.Xml.Serialization; 1884 1885 [SoapService(Style=SoapServiceStyle.RPC)] 1886 public class Test : WebService { 1887 [WebMethod] 1888 public int add(int a, int b) { 1889 return a + b; 1890 } 1891 } 1892 1893Another example from Kirill Gavrylyuk <kirillg@microsoft.com>: 1894 1895"You can insert [SoapRpcService()] attribute either on your class or on 1896operation level". 1897 1898 <%@ WebService Language=CS class="DataType.StringTest"%> 1899 1900 namespace DataType { 1901 1902 using System; 1903 using System.Web.Services; 1904 using System.Web.Services.Protocols; 1905 using System.Web.Services.Description; 1906 1907 [SoapRpcService()] 1908 public class StringTest: WebService { 1909 [WebMethod] 1910 [SoapRpcMethod()] 1911 public string RetString(string x) { 1912 return(x); 1913 } 1914 } 1915 } 1916 1917Example from Yann Christensen <yannc@microsoft.com>: 1918 1919 using System; 1920 using System.Web.Services; 1921 using System.Web.Services.Protocols; 1922 1923 namespace Currency { 1924 [WebService(Namespace="http://www.yourdomain.com/example")] 1925 [SoapRpcService] 1926 public class Exchange { 1927 [WebMethod] 1928 public double getRate(String country, String country2) { 1929 return 122.69; 1930 } 1931 } 1932 } 1933 1934=back 1935 1936=back 1937 1938Thanks to 1939 Petr Janata <petr.janata@i.cz>, 1940 Stefan Pharies <stefanph@microsoft.com>, 1941 Brian Jepson <bjepson@jepstone.net>, and others 1942for description and examples. 1943 1944=back 1945 1946=head2 TROUBLESHOOTING 1947 1948=over 4 1949 1950=item +autodispatch doesn't work in Perl 5.8 1951 1952There is a bug in Perl 5.8's UNIVERSAL::AUTOLOAD functionality that prevents 1953the +autodispatch functionality from working properly. The workaround is to 1954use dispatch_from instead. Where you might normally do something like this: 1955 1956 use Some::Module; 1957 use SOAP::Lite +autodispatch => 1958 uri => 'urn:Foo' 1959 proxy => 'http://...'; 1960 1961You would do something like this: 1962 1963 use SOAP::Lite dispatch_from(Some::Module) => 1964 uri => 'urn:Foo' 1965 proxy => 'http://...'; 1966 1967=item HTTP transport 1968 1969See L<TROUBLESHOOTING|SOAP::Transport::HTTP/"TROUBLESHOOTING"> section in 1970documentation for HTTP transport. 1971 1972=item COM interface 1973 1974=over 4 1975 1976=item Can't call method "server" on undefined value 1977 1978Probably you didn't register Lite.dll with 'regsvr32 Lite.dll' 1979 1980=item Failed to load PerlCtrl runtime 1981 1982Probably you have two Perl installations in different places and 1983ActiveState's Perl isn't the first Perl specified in PATH. Rename the 1984directory with another Perl (at least during the DLL's startup) or put 1985ActiveState's Perl on the first place in PATH. 1986 1987=back 1988 1989=item XML Parsers 1990 1991=over 4 1992 1993=item SAX parsers 1994 1995SAX 2.0 has a known bug in org.xml.sax.helpers.ParserAdapter 1996 rejects Namespace prefix used before declaration 1997 1998(http://www.megginson.com/SAX/index.html). 1999 2000That means that in some cases SOAP messages created by SOAP::Lite may not 2001be parsed properly by SAX2/Java parser, because Envelope 2002element contains namespace declarations and attributes that depends on this 2003declarations. According to XML specification order of these attributes is 2004not significant. SOAP::Lite does NOT have a problem parsing such messages. 2005 2006Thanks to Steve Alpert (Steve_Alpert@idx.com) for pointing on it. 2007 2008=back 2009 2010=back 2011 2012=head2 PERFORMANCE 2013 2014=over 4 2015 2016=item Processing of XML encoded fragments 2017 2018SOAP::Lite is based on XML::Parser which is basically wrapper around James 2019Clark's expat parser. Expat's behavior for parsing XML encoded string can 2020affect processing messages that have lot of encoded entities, like XML 2021fragments, encoded as strings. Providing low-level details, parser will call 2022char() callback for every portion of processed stream, but individually for 2023every processed entity or newline. It can lead to lot of calls and additional 2024memory manager expenses even for small messages. By contrast, XML messages 2025which are encoded as base64, don't have this problem and difference in 2026processing time can be significant. For XML encoded string that has about 20 2027lines and 30 tags, number of call could be about 100 instead of one for 2028the same string encoded as base64. 2029 2030Since it is parser's feature there is NO fix for this behavior (let me know 2031if you find one), especially because you need to parse message you already 2032got (and you cannot control content of this message), however, if your are 2033in charge for both ends of processing you can switch encoding to base64 on 2034sender's side. It will definitely work with SOAP::Lite and it B<may> work with 2035other toolkits/implementations also, but obviously I cannot guarantee that. 2036 2037If you want to encode specific string as base64, just do 2038C<< SOAP::Data->type(base64 => $string) >> either on client or on server 2039side. If you want change behavior for specific instance of SOAP::Lite, you 2040may subclass C<SOAP::Serializer>, override C<as_string()> method that is 2041responsible for string encoding (take a look into C<as_base64()>) and 2042specify B<new> serializer class for your SOAP::Lite object with: 2043 2044 my $soap = new SOAP::Lite 2045 serializer => My::Serializer->new, 2046 ..... other parameters 2047 2048or on server side: 2049 2050 my $server = new SOAP::Transport::HTTP::Daemon # or any other server 2051 serializer => My::Serializer->new, 2052 ..... other parameters 2053 2054If you want to change this behavior for B<all> instances of SOAP::Lite, just 2055substitute C<as_string()> method with C<as_base64()> somewhere in your 2056code B<after> C<use SOAP::Lite> and B<before> actual processing/sending: 2057 2058 *SOAP::Serializer::as_string = \&SOAP::Serializer::as_base64; 2059 2060Be warned that last two methods will affect B<all> strings and convert them 2061into base64 encoded. It doesn't make any difference for SOAP::Lite, but it 2062B<may> make a difference for other toolkits. 2063 2064=back 2065 2066=head2 WEBHOSTING INSTALLATION 2067 2068As soon as you have telnet access to the box and XML::Parser is already 2069installed there (or you have Perl 5.6 and can use XML::Parser::Lite) you 2070may install your own copy of SOAP::Lite even if hosting provider doesn't 2071want to do it. 2072 2073Setup C<PERL5LIB> environment variable. Depending on your shell it may 2074look like: 2075 2076 PERL5LIB=/you/home/directory/lib; export PERL5LIB 2077 2078C<lib> here is the name of directory where all libraries will be installed 2079under your home directory. 2080 2081Run CPAN module with 2082 2083 perl -MCPAN -e shell 2084 2085and run three commands from CPAN shell 2086 2087 > o conf make_arg -I~/lib 2088 > o conf make_install_arg -I~/lib 2089 > o conf makepl_arg LIB=~/lib PREFIX=~ INSTALLMAN1DIR=~/man/man1 INSTALLMAN3DIR=~/man/man3 2090 2091C<LIB> will specify directory where all libraries will reside. 2092 2093C<PREFIX> will specify prefix for all directories (like F<lib>, F<bin>, F<man>, 2094though it doesn't work in all cases for some reason). 2095 2096C<INSTALLMAN1DIR> and C<INSTALLMAN3DIR> specify directories for manuals 2097(if you don't specify them, install will fail because it'll try to setup 2098it in default directory and you don't have permissions for that). 2099 2100Then run: 2101 2102 > install SOAP::Lite 2103 2104Now in your scripts you need to specify: 2105 2106 use lib '/your/home/directory/lib'; 2107 2108somewhere before C<'use SOAP::Lite;'> 2109 2110=head1 BUGS AND LIMITATIONS 2111 2112=over 4 2113 2114=item * 2115 2116No support for multidimensional, partially transmitted and sparse arrays 2117(however arrays of arrays are supported, as well as any other data 2118structures, and you can add your own implementation with SOAP::Data). 2119 2120=item * 2121 2122Limited support for WSDL schema. 2123 2124=item * 2125 2126XML::Parser::Lite relies on Unicode support in Perl and doesn't do 2127entity decoding. 2128 2129=item * 2130 2131Limited support for mustUnderstand and Actor attributes. 2132 2133=back 2134 2135=head1 PLATFORMS 2136 2137=over 4 2138 2139=item MacOS 2140 2141Information about XML::Parser for MacPerl could be found here: 2142http://bumppo.net/lists/macperl-modules/1999/07/msg00047.html 2143 2144Compiled XML::Parser for MacOS could be found here: 2145http://www.perl.com/CPAN-local/authors/id/A/AS/ASANDSTRM/XML-Parser-2.27-bin-1-MacOS.tgz 2146 2147=back 2148 2149=head1 AVAILABILITY 2150 2151You can download the latest version SOAP::Lite for Unix or SOAP::Lite for Win32 from the following sources: 2152 2153* SOAP::Lite Homepage: http://soaplite.com/ 2154* CPAN: http://search.cpan.org/search?dist=SOAP-Lite 2155* Sourceforge: http://sourceforge.net/projects/soaplite/ 2156 2157You are welcome to send e-mail to the maintainers of SOAP::Lite with your 2158with your comments, suggestions, bug reports and complaints. 2159 2160=head1 SEE ALSO 2161 2162L<SOAP> SOAP/Perl library from Keith Brown ( http://www.develop.com/soap/ ) or 2163( http://search.cpan.org/search?dist=SOAP ) 2164 2165=head1 ACKNOWLEDGMENTS 2166 2167A lot of thanks to 2168 Tony Hong <thong@xmethods.net>, 2169 Petr Janata <petr.janata@i.cz>, 2170 Murray Nesbitt <murray@ActiveState.com>, 2171 Robert Barta <rho@bigpond.net.au>, 2172 Gisle Aas <gisle@ActiveState.com>, 2173 Carl K. Cunningham <cc@roberts.de>, 2174 Graham Glass <graham-glass@mindspring.com>, 2175 Chris Radcliff <chris@velocigen.com>, 2176 Arun Kumar <u_arunkumar@yahoo.com>, 2177 and many many others 2178 2179for providing help, feedback, support, patches and comments. 2180 2181=head1 COPYRIGHT 2182 2183Copyright (C) 2000-2004 Paul Kulchenko. All rights reserved. 2184 2185This library is free software; you can redistribute it and/or modify 2186it under the same terms as Perl itself. 2187 2188=head1 AUTHORS 2189 2190Paul Kulchenko (paulclinger@yahoo.com) 2191Byrne Reese (byrne@majordojo.com) 2192 2193=cut 2194