1NAME 2 SOAP::Lite - Perl's Web Services Toolkit 3 4DESCRIPTION 5 SOAP::Lite is a collection of Perl modules which provides a simple and 6 lightweight interface to the Simple Object Access Protocol (SOAP) both 7 on client and server side. 8 9PERL VERSION WARNING 10 As of version SOAP::Lite version 1.0, no perl versions before 5.8 will 11 be supported. 12 13 SOAP::Lite 0.71 will be the last version of SOAP::Lite running on perl 14 5.005 15 16 Future versions of SOAP::Lite will require at least perl 5.6.0 17 18 If you have not had the time to upgrade your perl, you should consider 19 this now. 20 21OVERVIEW OF CLASSES AND PACKAGES 22 lib/SOAP/Lite.pm 23 SOAP::Lite - Main class provides all logic 24 25 SOAP::Transport - Transport backend 26 27 SOAP::Data - Data objects 28 29 SOAP::Header - Header Data Objects 30 31 SOAP::Serializer - Serializes data structures to SOAP messages 32 33 SOAP::Deserializer - Deserializes SOAP messages into SOAP::SOM 34 objects 35 36 SOAP::SOM - SOAP Message objects 37 38 SOAP::Constants - Provides access to common constants and defaults 39 40 SOAP::Trace - Tracing facilities 41 42 SOAP::Schema - Provides access and stub(s) for schema(s) 43 44 SOAP::Schema::WSDL - WSDL implementation for SOAP::Schema 45 46 SOAP::Server - Handles requests on server side 47 48 SOAP::Server::Object - Handles objects-by-reference 49 50 SOAP::Fault - Provides support for Faults on server side 51 52 SOAP::Utils - A set of private and public utility subroutines 53 54 lib/SOAP/Packager.pm 55 SOAP::Packager - Provides an abstract class for implementing custom 56 packagers. 57 58 SOAP::Packager::MIME - Provides MIME support to SOAP::Lite 59 60 SOAP::Packager::DIME - Provides DIME support to SOAP::Lite 61 62 lib/SOAP/Transport/HTTP.pm 63 SOAP::Transport::HTTP::Client - Client interface to HTTP transport 64 65 SOAP::Transport::HTTP::Server - Server interface to HTTP transport 66 67 SOAP::Transport::HTTP::CGI - CGI implementation of server interface 68 69 SOAP::Transport::HTTP::Daemon - Daemon implementation of server 70 interface 71 72 SOAP::Transport::HTTP::Apache - mod_perl implementation of server 73 interface 74 75 lib/SOAP/Transport/POP3.pm 76 SOAP::Transport::POP3::Server - Server interface to POP3 protocol 77 78 lib/SOAP/Transport/MAILTO.pm 79 SOAP::Transport::MAILTO::Client - Client interface to SMTP/sendmail 80 81 lib/SOAP/Transport/LOCAL.pm 82 SOAP::Transport::LOCAL::Client - Client interface to local transport 83 84 lib/SOAP/Transport/TCP.pm 85 SOAP::Transport::TCP::Server - Server interface to TCP protocol 86 87 SOAP::Transport::TCP::Client - Client interface to TCP protocol 88 89 lib/SOAP/Transport/IO.pm 90 SOAP::Transport::IO::Server - Server interface to IO transport 91 92METHODS 93 All accessor methods return the current value when called with no 94 arguments, while returning the object reference itself when called with 95 a new value. This allows the set-attribute calls to be chained together. 96 97 new(optional key/value pairs) 98 $client = SOAP::Lite->new(proxy => $endpoint) 99 100 Constructor. Many of the accessor methods defined here may be 101 initialized at creation by providing their name as a key, followed 102 by the desired value. The example provides the value for the proxy 103 element of the client. 104 105 transport(optional transport object) 106 $transp = $client->transport( ); 107 108 Gets or sets the transport object used for sending/receiving SOAP 109 messages. 110 111 See SOAP::Transport for details. 112 113 serializer(optional serializer object) 114 $serial = $client->serializer( ) 115 116 Gets or sets the serializer object used for creating XML messages. 117 118 See SOAP::Serializer for details. 119 120 packager(optional packager object) 121 $packager = $client->packager( ) 122 123 Provides access to the "SOAP::Packager" object that the client uses 124 to manage the use of attachments. The default packager is a MIME 125 packager, but unless you specify parts to send, no MIME formatting 126 will be done. 127 128 See also: SOAP::Packager. 129 130 proxy(endpoint, optional extra arguments) 131 $client->proxy('http://soap.xml.info/ endPoint'); 132 133 The proxy is the server or endpoint to which the client is going to 134 connect. This method allows the setting of the endpoint, along with 135 any extra information that the transport object may need when 136 communicating the request. 137 138 This method is actually an alias to the proxy method of 139 SOAP::Transport. It is the same as typing: 140 141 $client->transport( )->proxy(...arguments); 142 143 Extra parameters can be passed to proxy() - see below. 144 145 compress_threshold 146 See COMPRESSION in HTTP::Transport. 147 148 All initialization options from the underlying transport layer 149 The options for HTTP(S) are the same as for LWP::UserAgent's 150 new() method. 151 152 A common option is to create a instance of HTTP::Cookies and 153 pass it as cookie_jar option: 154 155 my $cookie_jar = HTTP::Cookies->new() 156 $client->proxy('http://www.example.org/webservice', 157 cookie_jar => $cookie_jar, 158 ); 159 160 For example, if you wish to set the HTTP timeout for a SOAP::Lite 161 client to 5 seconds, use the following code: 162 163 my $soap = SOAP::Lite 164 ->uri($uri) 165 ->proxy($proxyUrl, timeout => 5 ); 166 167 See LWP::UserAgent. 168 169 endpoint(optional new endpoint address) 170 $client->endpoint('http://soap.xml.info/ newPoint') 171 172 It may be preferable to set a new endpoint without the additional 173 work of examining the new address for protocol information and 174 checking to ensure the support code is loaded and available. This 175 method allows the caller to change the endpoint that the client is 176 currently set to connect to, without reloading the relevant 177 transport code. Note that the proxy method must have been called 178 before this method is used. 179 180 service(service URL) 181 $client->service('http://svc.perl.org/Svc.wsdl'); 182 183 "SOAP::Lite" offers some support for creating method stubs from 184 service descriptions. At present, only WSDL support is in place. 185 This method loads the specified WSDL schema and uses it as the basis 186 for generating stubs. 187 188 outputxml(boolean) 189 $client->outputxml('true'); 190 191 When set to a true value, the raw XML is returned by the call to a 192 remote method. 193 194 The default is to return the a SOAP::SOM object (false). 195 196 autotype(boolean) 197 $client->autotype(0); 198 199 This method is a shortcut for: 200 201 $client->serializer->autotype(boolean); 202 203 By default, the serializer tries to automatically deduce types for 204 the data being sent in a message. Setting a false value with this 205 method disables the behavior. 206 207 readable(boolean) 208 $client->readable(1); 209 210 This method is a shortcut for: 211 212 $client->serializer->readable(boolean); 213 214 When this is used to set a true value for this property, the 215 generated XML sent to the endpoint has extra characters (spaces and 216 new lines) added in to make the XML itself more readable to human 217 eyes (presumably for debugging). The default is to not send any 218 additional characters. 219 220 default_ns($uri) 221 Sets the default namespace for the request to the specified uri. 222 This overrides any previous namespace declaration that may have been 223 set using a previous call to "ns()" or "default_ns()". Setting the 224 default namespace causes elements to be serialized without a 225 namespace prefix, like this: 226 227 <soap:Envelope> 228 <soap:Body> 229 <myMethod xmlns="http://www.someuri.com"> 230 <foo /> 231 </myMethod> 232 </soap:Body> 233 </soap:Envelope> 234 235 Some .NET web services have been reported to require this XML 236 namespace idiom. 237 238 ns($uri,$prefix=undef) 239 Sets the namespace uri and optionally the namespace prefix for the 240 request to the specified values. This overrides any previous 241 namespace declaration that may have been set using a previous call 242 to "ns()" or "default_ns()". 243 244 If a prefix is not specified, one will be generated for you 245 automatically. Setting the namespace causes elements to be 246 serialized with a declared namespace prefix, like this: 247 248 <soap:Envelope> 249 <soap:Body> 250 <my:myMethod xmlns:my="http://www.someuri.com"> 251 <my:foo /> 252 </my:myMethod> 253 </soap:Body> 254 </soap:Envelope> 255 256 use_prefix(boolean) 257 Deprecated. Use the "ns()" and "default_ns" methods described above. 258 259 Shortcut for "serializer->use_prefix()". This lets you turn on/off 260 the use of a namespace prefix for the children of the /Envelope/Body 261 element. Default is 'true'. 262 263 When use_prefix is set to 'true', serialized XML will look like 264 this: 265 266 <SOAP-ENV:Envelope ...attributes skipped> 267 <SOAP-ENV:Body> 268 <namesp1:mymethod xmlns:namesp1="urn:MyURI" /> 269 </SOAP-ENV:Body> 270 </SOAP-ENV:Envelope> 271 272 When use_prefix is set to 'false', serialized XML will look like 273 this: 274 275 <SOAP-ENV:Envelope ...attributes skipped> 276 <SOAP-ENV:Body> 277 <mymethod xmlns="urn:MyURI" /> 278 </SOAP-ENV:Body> 279 </SOAP-ENV:Envelope> 280 281 Some .NET web services have been reported to require this XML 282 namespace idiom. 283 284 soapversion(optional value) 285 $client->soapversion('1.2'); 286 287 If no parameter is given, returns the current version of SOAP that 288 is being used by the client object to encode requests. If a 289 parameter is given, the method attempts to set that as the version 290 of SOAP being used. 291 292 The value should be either 1.1 or 1.2. 293 294 envprefix(QName) 295 $client->envprefix('env'); 296 297 This method is a shortcut for: 298 299 $client->serializer->envprefix(QName); 300 301 Gets or sets the namespace prefix for the SOAP namespace. The 302 default is SOAP. 303 304 The prefix itself has no meaning, but applications may wish to chose 305 one explicitly to denote different versions of SOAP or the like. 306 307 encprefix(QName) 308 $client->encprefix('enc'); 309 310 This method is a shortcut for: 311 312 $client->serializer->encprefix(QName); 313 314 Gets or sets the namespace prefix for the encoding rules namespace. 315 The default value is SOAP-ENC. 316 317 While it may seem to be an unnecessary operation to set a value that 318 isn't relevant to the message, such as the namespace labels for the 319 envelope and encoding URNs, the ability to set these labels explicitly 320 can prove to be a great aid in distinguishing and debugging messages on 321 the server side of operations. 322 323 encoding(encoding URN) 324 $client->encoding($soap_12_encoding_URN); 325 326 This method is a shortcut for: 327 328 $client->serializer->encoding(args); 329 330 Where the earlier method dealt with the label used for the 331 attributes related to the SOAP encoding scheme, this method actually 332 sets the URN to be specified as the encoding scheme for the message. 333 The default is to specify the encoding for SOAP 1.1, so this is 334 handy for applications that need to encode according to SOAP 1.2 335 rules. 336 337 typelookup 338 $client->typelookup; 339 340 This method is a shortcut for: 341 342 $client->serializer->typelookup; 343 344 Gives the application access to the type-lookup table from the 345 serializer object. See the section on SOAP::Serializer. 346 347 uri(service specifier) 348 Deprecated - the "uri" subroutine is deprecated in order to provide 349 a more intuitive naming scheme for subroutines that set namespaces. 350 In the future, you will be required to use either the "ns()" or 351 "default_ns()" subroutines instead of "uri()". 352 353 $client->uri($service_uri); 354 355 This method is a shortcut for: 356 357 $client->serializer->uri(service); 358 359 The URI associated with this accessor on a client object is the 360 service-specifier for the request, often encoded for HTTP-based 361 requests as the SOAPAction header. While the names may seem 362 confusing, this method doesn't specify the endpoint itself. In most 363 circumstances, the "uri" refers to the namespace used for the 364 request. 365 366 Often times, the value may look like a valid URL. Despite this, it 367 doesn't have to point to an existing resource (and often doesn't). 368 This method sets and retrieves this value from the object. Note that 369 no transport code is triggered by this because it has no direct 370 effect on the transport of the object. 371 372 multirefinplace(boolean) 373 $client->multirefinplace(1); 374 375 This method is a shortcut for: 376 377 $client->serializer->multirefinplace(boolean); 378 379 Controls how the serializer handles values that have multiple 380 references to them. Recall from previous SOAP chapters that a value 381 may be tagged with an identifier, then referred to in several 382 places. When this is the case for a value, the serializer defaults 383 to putting the data element towards the top of the message, right 384 after the opening tag of the method-specification. It is serialized 385 as a standalone entity with an ID that is then referenced at the 386 relevant places later on. If this method is used to set a true 387 value, the behavior is different. When the multirefinplace attribute 388 is true, the data is serialized at the first place that references 389 it, rather than as a separate element higher up in the body. This is 390 more compact but may be harder to read or trace in a debugging 391 environment. 392 393 parts( ARRAY ) 394 Used to specify an array of MIME::Entity's to be attached to the 395 transmitted SOAP message. Attachments that are returned in a 396 response can be accessed by "SOAP::SOM::parts()". 397 398 self 399 $ref = SOAP::Lite->self; 400 401 Returns an object reference to the default global object the 402 "SOAP::Lite" package maintains. This is the object that processes 403 many of the arguments when provided on the use line. 404 405 The following method isn't an accessor style of method but neither does 406 it fit with the group that immediately follows it: 407 408 call(arguments) 409 $client->call($method => @arguments); 410 411 As has been illustrated in previous chapters, the "SOAP::Lite" 412 client objects can manage remote calls with auto-dispatching using 413 some of Perl's more elaborate features. call is used when the 414 application wants a greater degree of control over the details of 415 the call itself. The method may be built up from a SOAP::Data 416 object, so as to allow full control over the namespace associated 417 with the tag, as well as other attributes like encoding. This is 418 also important for calling methods that contain characters not 419 allowable in Perl function names, such as A.B.C. 420 421 The next four methods used in the "SOAP::Lite" class are geared towards 422 handling the types of events than can occur during the message 423 lifecycle. Each of these sets up a callback for the event in question: 424 425 on_action(callback) 426 $client->on_action(sub { qq("$_[0]") }); 427 428 Triggered when the transport object sets up the SOAPAction header 429 for an HTTP-based call. The default is to set the header to the 430 string, uri#method, in which URI is the value set by the uri method 431 described earlier, and method is the name of the method being 432 called. When called, the routine referenced (or the closure, if 433 specified as in the example) is given two arguments, uri and method, 434 in that order. 435 436 .NET web services usually expect "/" as separator for "uri" and 437 "method". To change SOAP::Lite's behaviour to use uri/method as 438 SOAPAction header, use the following code: 439 440 $client->on_action( sub { join '/', @_ } ); 441 =item on_fault(callback) 442 443 $client->on_fault(sub { popup_dialog($_[1]) }); 444 445 Triggered when a method call results in a fault response from the 446 server. When it is called, the argument list is first the client 447 object itself, followed by the object that encapsulates the fault. 448 In the example, the fault object is passed (without the client 449 object) to a hypothetical GUI function that presents an error dialog 450 with the text of fault extracted from the object (which is covered 451 shortly under the SOAP::SOM methods). 452 453 on_nonserialized(callback) 454 $client->on_nonserialized(sub { die "$_[0]?!?" }); 455 456 Occasionally, the serializer may be given data it can't turn into 457 SOAP-savvy XML; for example, if a program bug results in a code 458 reference or something similar being passed in as a parameter to 459 method call. When that happens, this callback is activated, with one 460 argument. That argument is the data item that could not be 461 understood. It will be the only argument. If the routine returns, 462 the return value is pasted into the message as the serialization. 463 Generally, an error is in order, and this callback allows for 464 control over signaling that error. 465 466 on_debug(callback) 467 $client->on_debug(sub { print @_ }); 468 469 Deprecated. Use the global +debug and +trace facilities described in 470 SOAP::Trace 471 472 Note that this method will not work as expected: Instead of 473 affecting the debugging behaviour of the object called on, it will 474 globally affect the debugging behaviour for all objects of that 475 class. 476 477WRITING A SOAP CLIENT 478 This chapter guides you to writing a SOAP client by example. 479 480 The SOAP service to be accessed is a simple variation of the well-known 481 hello world program. It accepts two parameters, a name and a given name, 482 and returns "Hello $given_name $name". 483 484 We will use "Martin Kutter" as the name for the call, so all variants 485 will print the following message on success: 486 487 Hello Martin Kutter! 488 489 SOAP message styles 490 There are three common (and one less common) variants of SOAP messages. 491 492 These address the message style (positional parameters vs. specified 493 message documents) and encoding (as-is vs. typed). 494 495 The different message styles are: 496 497 * rpc/encoded 498 499 Typed, positional parameters. Widely used in scripting languages. 500 The type of the arguments is included in the message. Arrays and the 501 like may be encoded using SOAP encoding rules (or others). 502 503 * rpc/literal 504 505 As-is, positional parameters. The type of arguments is defined by 506 some pre-exchanged interface definition. 507 508 * document/encoded 509 510 Specified message with typed elements. Rarely used. 511 512 * document/literal 513 514 Specified message with as-is elements. The message specification and 515 element types are defined by some pre-exchanged interface 516 definition. 517 518 As of 2008, document/literal has become the predominant SOAP message 519 variant. rpc/literal and rpc/encoded are still in use, mainly with 520 scripting languages, while document/encoded is hardly used at all. 521 522 You will see clients for the rpc/encoded and document/literal SOAP 523 variants in this section. 524 525 Example implementations 526 RPC/ENCODED 527 Rpc/encoded is most popular with scripting languages like perl, php and 528 python without the use of a WSDL. Usual method descriptions look like 529 this: 530 531 Method: sayHello(string, string) 532 Parameters: 533 name: string 534 givenName: string 535 536 Such a description usually means that you can call a method named 537 "sayHello" with two positional parameters, "name" and "givenName", which 538 both are strings. 539 540 The message corresponding to this description looks somewhat like this: 541 542 <sayHello xmlns="urn:HelloWorld"> 543 <s-gensym01 xsi:type="xsd:string">Kutter</s-gensym01> 544 <s-gensym02 xsi:type="xsd:string">Martin</s-gensym02> 545 </sayHello> 546 547 Any XML tag names may be used instead of the "s-gensym01" stuff - 548 parameters are positional, the tag names have no meaning. 549 550 A client producing such a call is implemented like this: 551 552 use SOAP::Lite; 553 my $soap = SOAP::Lite->new( proxy => 'http://localhost:81/soap-wsdl-test/helloworld.pl'); 554 $soap->default_ns('urn:HelloWorld'); 555 my $som = $soap->call('sayHello', 'Kutter', 'Martin'); 556 die $som->faultstring if ($som->fault); 557 print $som->result, "\n"; 558 559 You can of course use a one-liner, too... 560 561 Sometimes, rpc/encoded interfaces are described with WSDL definitions. A 562 WSDL accepting "named" parameters with rpc/encoded looks like this: 563 564 <definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 565 xmlns:s="http://www.w3.org/2001/XMLSchema" 566 xmlns:s0="urn:HelloWorld" 567 targetNamespace="urn:HelloWorld" 568 xmlns="http://schemas.xmlsoap.org/wsdl/"> 569 <types> 570 <s:schema targetNamespace="urn:HelloWorld"> 571 </s:schema> 572 </types> 573 <message name="sayHello"> 574 <part name="name" type="s:string" /> 575 <part name="givenName" type="s:string" /> 576 </message> 577 <message name="sayHelloResponse"> 578 <part name="sayHelloResult" type="s:string" /> 579 </message> 580 581 <portType name="Service1Soap"> 582 <operation name="sayHello"> 583 <input message="s0:sayHello" /> 584 <output message="s0:sayHelloResponse" /> 585 </operation> 586 </portType> 587 588 <binding name="Service1Soap" type="s0:Service1Soap"> 589 <soap:binding transport="http://schemas.xmlsoap.org/soap/http" 590 style="rpc" /> 591 <operation name="sayHello"> 592 <soap:operation soapAction="urn:HelloWorld#sayHello"/> 593 <input> 594 <soap:body use="encoded" 595 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> 596 </input> 597 <output> 598 <soap:body use="encoded" 599 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> 600 </output> 601 </operation> 602 </binding> 603 <service name="HelloWorld"> 604 <port name="HelloWorldSoap" binding="s0:Service1Soap"> 605 <soap:address location="http://localhost:81/soap-wsdl-test/helloworld.pl" /> 606 </port> 607 </service> 608 </definitions> 609 610 The message corresponding to this schema looks like this: 611 612 <sayHello xmlns="urn:HelloWorld"> 613 <name xsi:type="xsd:string">Kutter</name> 614 <givenName xsi:type="xsd:string">Martin</givenName> 615 </sayHello> 616 617 A web service client using this schema looks like this: 618 619 use SOAP::Lite; 620 my $soap = SOAP::Lite->service("file:say_hello_rpcenc.wsdl"); 621 eval { my $result = $soap->sayHello('Kutter', 'Martin'); }; 622 if ($@) { 623 die $@; 624 } 625 print $som->result(); 626 627 You may of course also use the following one-liner: 628 629 perl -MSOAP::Lite -e 'print SOAP::Lite->service("file:say_hello_rpcenc.wsdl")\ 630 ->sayHello('Kutter', 'Martin'), "\n";' 631 632 A web service client (without a service description) looks like this. 633 634 use SOAP::Lite; 635 my $soap = SOAP::Lite->new( proxy => 'http://localhost:81/soap-wsdl-test/helloworld.pl'); 636 $soap->default_ns('urn:HelloWorld'); 637 my $som = $soap->call('sayHello', 638 SOAP::Data->name('name')->value('Kutter'), 639 SOAP::Data->name('givenName')->value('Martin') 640 ); 641 die $som->faultstring if ($som->fault); 642 print $som->result, "\n"; 643 644 RPC/LITERAL 645 SOAP web services using the document/literal message encoding are 646 usually described by some Web Service Definition. Our web service has 647 the following WSDL description: 648 649 <definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 650 xmlns:s="http://www.w3.org/2001/XMLSchema" 651 xmlns:s0="urn:HelloWorld" 652 targetNamespace="urn:HelloWorld" 653 xmlns="http://schemas.xmlsoap.org/wsdl/"> 654 <types> 655 <s:schema targetNamespace="urn:HelloWorld"> 656 <s:complexType name="sayHello"> 657 <s:sequence> 658 <s:element minOccurs="0" maxOccurs="1" name="name" 659 type="s:string" /> 660 <s:element minOccurs="0" maxOccurs="1" name="givenName" 661 type="s:string" nillable="1" /> 662 </s:sequence> 663 </s:complexType> 664 665 <s:complexType name="sayHelloResponse"> 666 <s:sequence> 667 <s:element minOccurs="0" maxOccurs="1" name="sayHelloResult" 668 type="s:string" /> 669 </s:sequence> 670 </s:complexType> 671 </s:schema> 672 </types> 673 <message name="sayHello"> 674 <part name="parameters" type="s0:sayHello" /> 675 </message> 676 <message name="sayHelloResponse"> 677 <part name="parameters" type="s0:sayHelloResponse" /> 678 </message> 679 680 <portType name="Service1Soap"> 681 <operation name="sayHello"> 682 <input message="s0:sayHello" /> 683 <output message="s0:sayHelloResponse" /> 684 </operation> 685 </portType> 686 687 <binding name="Service1Soap" type="s0:Service1Soap"> 688 <soap:binding transport="http://schemas.xmlsoap.org/soap/http" 689 style="rpc" /> 690 <operation name="sayHello"> 691 <soap:operation soapAction="urn:HelloWorld#sayHello"/> 692 <input> 693 <soap:body use="literal" namespace="urn:HelloWorld"/> 694 </input> 695 <output> 696 <soap:body use="literal" namespace="urn:HelloWorld"/> 697 </output> 698 </operation> 699 </binding> 700 <service name="HelloWorld"> 701 <port name="HelloWorldSoap" binding="s0:Service1Soap"> 702 <soap:address location="http://localhost:80//helloworld.pl" /> 703 </port> 704 </service> 705 </definitions> 706 707 The XML message (inside the SOAP Envelope) look like this: 708 709 <ns0:sayHello xmlns:ns0="urn:HelloWorld"> 710 <parameters> 711 <name>Kutter</name> 712 <givenName>Martin</givenName> 713 </parameters> 714 </ns0:sayHello> 715 716 <sayHelloResponse xmlns:ns0="urn:HelloWorld"> 717 <parameters> 718 <sayHelloResult>Hello Martin Kutter!</sayHelloResult> 719 </parameters> 720 </sayHelloResponse> 721 722 This is the SOAP::Lite implementation for the web service client: 723 724 use SOAP::Lite +trace; 725 my $soap = SOAP::Lite->new( proxy => 'http://localhost:80/helloworld.pl'); 726 727 $soap->on_action( sub { "urn:HelloWorld#sayHello" }); 728 $soap->autotype(0)->readable(1); 729 $soap->default_ns('urn:HelloWorld'); 730 731 my $som = $soap->call('sayHello', SOAP::Data->name('parameters')->value( 732 \SOAP::Data->value([ 733 SOAP::Data->name('name')->value( 'Kutter' ), 734 SOAP::Data->name('givenName')->value('Martin'), 735 ])) 736 ); 737 738 die $som->fault->{ faultstring } if ($som->fault); 739 print $som->result, "\n"; 740 741 DOCUMENT/LITERAL 742 SOAP web services using the document/literal message encoding are 743 usually described by some Web Service Definition. Our web service has 744 the following WSDL description: 745 746 <definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 747 xmlns:s="http://www.w3.org/2001/XMLSchema" 748 xmlns:s0="urn:HelloWorld" 749 targetNamespace="urn:HelloWorld" 750 xmlns="http://schemas.xmlsoap.org/wsdl/"> 751 <types> 752 <s:schema targetNamespace="urn:HelloWorld"> 753 <s:element name="sayHello"> 754 <s:complexType> 755 <s:sequence> 756 <s:element minOccurs="0" maxOccurs="1" name="name" type="s:string" /> 757 <s:element minOccurs="0" maxOccurs="1" name="givenName" type="s:string" nillable="1" /> 758 </s:sequence> 759 </s:complexType> 760 </s:element> 761 762 <s:element name="sayHelloResponse"> 763 <s:complexType> 764 <s:sequence> 765 <s:element minOccurs="0" maxOccurs="1" name="sayHelloResult" type="s:string" /> 766 </s:sequence> 767 </s:complexType> 768 </s:element> 769 </types> 770 <message name="sayHelloSoapIn"> 771 <part name="parameters" element="s0:sayHello" /> 772 </message> 773 <message name="sayHelloSoapOut"> 774 <part name="parameters" element="s0:sayHelloResponse" /> 775 </message> 776 777 <portType name="Service1Soap"> 778 <operation name="sayHello"> 779 <input message="s0:sayHelloSoapIn" /> 780 <output message="s0:sayHelloSoapOut" /> 781 </operation> 782 </portType> 783 784 <binding name="Service1Soap" type="s0:Service1Soap"> 785 <soap:binding transport="http://schemas.xmlsoap.org/soap/http" 786 style="document" /> 787 <operation name="sayHello"> 788 <soap:operation soapAction="urn:HelloWorld#sayHello"/> 789 <input> 790 <soap:body use="literal" /> 791 </input> 792 <output> 793 <soap:body use="literal" /> 794 </output> 795 </operation> 796 </binding> 797 <service name="HelloWorld"> 798 <port name="HelloWorldSoap" binding="s0:Service1Soap"> 799 <soap:address location="http://localhost:80//helloworld.pl" /> 800 </port> 801 </service> 802 </definitions> 803 804 The XML message (inside the SOAP Envelope) look like this: 805 806 <sayHello xmlns="urn:HelloWorld"> 807 <name>Kutter</name> 808 <givenName>Martin</givenName> 809 </sayHello> 810 811 <sayHelloResponse> 812 <sayHelloResult>Hello Martin Kutter!</sayHelloResult> 813 </sayHelloResponse> 814 815 You can call this web service with the following client code: 816 817 use SOAP::Lite; 818 my $soap = SOAP::Lite->new( proxy => 'http://localhost:80/helloworld.pl'); 819 820 $soap->on_action( sub { "urn:HelloWorld#sayHello" }); 821 $soap->autotype(0); 822 $soap->default_ns('urn:HelloWorld'); 823 824 my $som = $soap->call("sayHello", 825 SOAP::Data->name('name')->value( 'Kutter' ), 826 SOAP::Data->name('givenName')->value('Martin'), 827 ); 828 829 die $som->fault->{ faultstring } if ($som->fault); 830 print $som->result, "\n"; 831 832 Differences between the implementations 833 You may have noticed that there's little difference between the 834 rpc/encoded, rpc/literal and the document/literal example's 835 implementation. In fact, from SOAP::Lite's point of view, the only 836 differences between rpc/literal and document/literal that parameters are 837 always named. 838 839 In our example, the rpc/encoded variant already used named parameters 840 (by using two messages), so there's no difference at all. 841 842 You may have noticed the somewhat strange idiom for passing a list of 843 named paraneters in the rpc/literal example: 844 845 my $som = $soap->call('sayHello', SOAP::Data->name('parameters')->value( 846 \SOAP::Data->value([ 847 SOAP::Data->name('name')->value( 'Kutter' ), 848 SOAP::Data->name('givenName')->value('Martin'), 849 ])) 850 ); 851 852 While SOAP::Data provides full control over the XML generated, passing 853 hash-like structures require additional coding. 854 855WRITING A SOAP SERVER 856 See SOAP::Server, or SOAP::Transport. 857 858FEATURES 859 ATTACHMENTS 860 "SOAP::Lite" features support for the SOAP with Attachments 861 specification. Currently, SOAP::Lite only supports MIME based 862 attachments. DIME based attachments are yet to be fully functional. 863 864 EXAMPLES 865 Client sending an attachment 866 "SOAP::Lite" clients can specify attachments to be sent along with a 867 request by using the "SOAP::Lite::parts()" method, which takes as an 868 argument an ARRAY of "MIME::Entity"'s. 869 870 use SOAP::Lite; 871 use MIME::Entity; 872 my $ent = build MIME::Entity 873 Type => "image/gif", 874 Encoding => "base64", 875 Path => "somefile.gif", 876 Filename => "saveme.gif", 877 Disposition => "attachment"; 878 my $som = SOAP::Lite 879 ->uri($SOME_NAMESPACE) 880 ->parts([ $ent ]) 881 ->proxy($SOME_HOST) 882 ->some_method(SOAP::Data->name("foo" => "bar")); 883 884 Client retrieving an attachment 885 A client accessing attachments that were returned in a response by using 886 the "SOAP::SOM::parts()" accessor. 887 888 use SOAP::Lite; 889 use MIME::Entity; 890 my $soap = SOAP::Lite 891 ->uri($NS) 892 ->proxy($HOST); 893 my $som = $soap->foo(); 894 foreach my $part (${$som->parts}) { 895 print $part->stringify; 896 } 897 898 Server receiving an attachment 899 Servers, like clients, use the SOAP::SOM module to access attachments 900 transmitted to it. 901 902 package Attachment; 903 use SOAP::Lite; 904 use MIME::Entity; 905 use strict; 906 use vars qw(@ISA); 907 @ISA = qw(SOAP::Server::Parameters); 908 sub someMethod { 909 my $self = shift; 910 my $envelope = pop; 911 foreach my $part (@{$envelope->parts}) { 912 print "AttachmentService: attachment found! (".ref($part).")\n"; 913 } 914 # do something 915 } 916 917 Server responding with an attachment 918 Servers wishing to return an attachment to the calling client need only 919 return "MIME::Entity" objects along with SOAP::Data elements, or any 920 other data intended for the response. 921 922 package Attachment; 923 use SOAP::Lite; 924 use MIME::Entity; 925 use strict; 926 use vars qw(@ISA); 927 @ISA = qw(SOAP::Server::Parameters); 928 sub someMethod { 929 my $self = shift; 930 my $envelope = pop; 931 my $ent = build MIME::Entity 932 'Id' => "<1234>", 933 'Type' => "text/xml", 934 'Path' => "some.xml", 935 'Filename' => "some.xml", 936 'Disposition' => "attachment"; 937 return SOAP::Data->name("foo" => "blah blah blah"),$ent; 938 } 939 940 DEFAULT SETTINGS 941 Though this feature looks similar to autodispatch they have (almost) 942 nothing in common. This capability allows you specify default settings 943 so that all objects created after that will be initialized with the 944 proper default settings. 945 946 If you wish to provide common "proxy()" or "uri()" settings for all 947 "SOAP::Lite" objects in your application you may do: 948 949 use SOAP::Lite 950 proxy => 'http://localhost/cgi-bin/soap.cgi', 951 uri => 'http://my.own.com/My/Examples'; 952 953 my $soap1 = new SOAP::Lite; # will get the same proxy()/uri() as above 954 print $soap1->getStateName(1)->result; 955 956 my $soap2 = SOAP::Lite->new; # same thing as above 957 print $soap2->getStateName(2)->result; 958 959 # or you may override any settings you want 960 my $soap3 = SOAP::Lite->proxy('http://localhost/'); 961 print $soap3->getStateName(1)->result; 962 963 Any "SOAP::Lite" properties can be propagated this way. Changes in 964 object copies will not affect global settings and you may still change 965 global settings with "SOAP::Lite->self" call which returns reference to 966 global object. Provided parameter will update this object and you can 967 even set it to "undef": 968 969 SOAP::Lite->self(undef); 970 971 The "use SOAP::Lite" syntax also lets you specify default event handlers 972 for your code. If you have different SOAP objects and want to share the 973 same "on_action()" (or "on_fault()" for that matter) handler. You can 974 specify "on_action()" during initialization for every object, but you 975 may also do: 976 977 use SOAP::Lite 978 on_action => sub {sprintf '%s#%s', @_}; 979 980 and this handler will be the default handler for all your SOAP objects. 981 You can override it if you specify a handler for a particular object. 982 See t/*.t for example of on_fault() handler. 983 984 Be warned, that since "use ..." is executed at compile time all "use" 985 statements will be executed before script execution that can make 986 unexpected results. Consider code: 987 988 use SOAP::Lite proxy => 'http://localhost/'; 989 print SOAP::Lite->getStateName(1)->result; 990 991 use SOAP::Lite proxy => 'http://localhost/cgi-bin/soap.cgi'; 992 print SOAP::Lite->getStateName(1)->result; 993 994 Both SOAP calls will go to 'http://localhost/cgi-bin/soap.cgi'. If you 995 want to execute "use" at run-time, put it in "eval": 996 997 eval "use SOAP::Lite proxy => 'http://localhost/cgi-bin/soap.cgi'; 1" or die; 998 999 Or alternatively, 1000 1001 SOAP::Lite->self->proxy('http://localhost/cgi-bin/soap.cgi'); 1002 1003 SETTING MAXIMUM MESSAGE SIZE 1004 One feature of "SOAP::Lite" is the ability to control the maximum size 1005 of a message a SOAP::Lite server will be allowed to process. To control 1006 this feature simply define $SOAP::Constants::MAX_CONTENT_SIZE in your 1007 code like so: 1008 1009 use SOAP::Transport::HTTP; 1010 use MIME::Entity; 1011 $SOAP::Constants::MAX_CONTENT_SIZE = 10000; 1012 SOAP::Transport::HTTP::CGI 1013 ->dispatch_to('TemperatureService') 1014 ->handle; 1015 1016 IN/OUT, OUT PARAMETERS AND AUTOBINDING 1017 "SOAP::Lite" gives you access to all parameters (both in/out and out) 1018 and also does some additional work for you. Lets consider following 1019 example: 1020 1021 <mehodResponse> 1022 <res1>name1</res1> 1023 <res2>name2</res2> 1024 <res3>name3</res3> 1025 </mehodResponse> 1026 1027 In that case: 1028 1029 $result = $r->result; # gives you 'name1' 1030 $paramout1 = $r->paramsout; # gives you 'name2', because of scalar context 1031 $paramout1 = ($r->paramsout)[0]; # gives you 'name2' also 1032 $paramout2 = ($r->paramsout)[1]; # gives you 'name3' 1033 1034 or 1035 1036 @paramsout = $r->paramsout; # gives you ARRAY of out parameters 1037 $paramout1 = $paramsout[0]; # gives you 'res2', same as ($r->paramsout)[0] 1038 $paramout2 = $paramsout[1]; # gives you 'res3', same as ($r->paramsout)[1] 1039 1040 Generally, if server returns "return (1,2,3)" you will get 1 as the 1041 result and 2 and 3 as out parameters. 1042 1043 If the server returns "return [1,2,3]" you will get an ARRAY reference 1044 from "result()" and "undef" from "paramsout()". 1045 1046 Results can be arbitrary complex: they can be an array references, they 1047 can be objects, they can be anything and still be returned by "result()" 1048 . If only one parameter is returned, "paramsout()" will return "undef". 1049 1050 Furthermore, if you have in your output parameters a parameter with the 1051 same signature (name+type) as in the input parameters this parameter 1052 will be mapped into your input automatically. For example: 1053 1054 Server Code: 1055 1056 sub mymethod { 1057 shift; # object/class reference 1058 my $param1 = shift; 1059 my $param2 = SOAP::Data->name('myparam' => shift() * 2); 1060 return $param1, $param2; 1061 } 1062 1063 Client Code: 1064 1065 $a = 10; 1066 $b = SOAP::Data->name('myparam' => 12); 1067 $result = $soap->mymethod($a, $b); 1068 1069 After that, "$result == 10 and $b->value == 24"! Magic? Sort of. 1070 1071 Autobinding gives it to you. That will work with objects also with one 1072 difference: you do not need to worry about the name and the type of 1073 object parameter. Consider the "PingPong" example 1074 (examples/My/PingPong.pm and examples/pingpong.pl): 1075 1076 Server Code: 1077 1078 package My::PingPong; 1079 1080 sub new { 1081 my $self = shift; 1082 my $class = ref($self) || $self; 1083 bless {_num=>shift} => $class; 1084 } 1085 1086 sub next { 1087 my $self = shift; 1088 $self->{_num}++; 1089 } 1090 1091 Client Code: 1092 1093 use SOAP::Lite +autodispatch => 1094 uri => 'urn:', 1095 proxy => 'http://localhost/'; 1096 1097 my $p = My::PingPong->new(10); # $p->{_num} is 10 now, real object returned 1098 print $p->next, "\n"; # $p->{_num} is 11 now!, object autobinded 1099 1100 STATIC AND DYNAMIC SERVICE DEPLOYMENT 1101 Let us scrutinize the deployment process. When designing your SOAP 1102 server you can consider two kind of deployment: static and dynamic. For 1103 both, static and dynamic, you should specify "MODULE", "MODULE::method", 1104 "method" or "PATH/" when creating "use"ing the SOAP::Lite module. The 1105 difference between static and dynamic deployment is that in case of 1106 'dynamic', any module which is not present will be loaded on demand. See 1107 the "SECURITY" section for detailed description. 1108 1109 When statically deploying a SOAP Server, you need to know all modules 1110 handling SOAP requests before. 1111 1112 Dynamic deployment allows extending your SOAP Server's interface by just 1113 installing another module into the dispatch_to path (see below). 1114 1115 STATIC DEPLOYMENT EXAMPLE 1116 use SOAP::Transport::HTTP; 1117 use My::Examples; # module is preloaded 1118 1119 SOAP::Transport::HTTP::CGI 1120 # deployed module should be present here or client will get 1121 # 'access denied' 1122 -> dispatch_to('My::Examples') 1123 -> handle; 1124 1125 For static deployment you should specify the MODULE name directly. 1126 1127 You should also use static binding when you have several different 1128 classes in one file and want to make them available for SOAP calls. 1129 1130 DYNAMIC DEPLOYMENT EXAMPLE 1131 use SOAP::Transport::HTTP; 1132 # name is unknown, module will be loaded on demand 1133 1134 SOAP::Transport::HTTP::CGI 1135 # deployed module should be present here or client will get 'access denied' 1136 -> dispatch_to('/Your/Path/To/Deployed/Modules', 'My::Examples') 1137 -> handle; 1138 1139 For dynamic deployment you can specify the name either directly (in that 1140 case it will be "require"d without any restriction) or indirectly, with 1141 a PATH. In that case, the ONLY path that will be available will be the 1142 PATH given to the dispatch_to() method). For information how to handle 1143 this situation see "SECURITY" section. 1144 1145 SUMMARY 1146 dispatch_to( 1147 # dynamic dispatch that allows access to ALL modules in specified directory 1148 PATH/TO/MODULES 1149 # 1. specifies directory 1150 # -- AND -- 1151 # 2. gives access to ALL modules in this directory without limits 1152 1153 # static dispatch that allows access to ALL methods in particular MODULE 1154 MODULE 1155 # 1. gives access to particular module (all available methods) 1156 # PREREQUISITES: 1157 # module should be loaded manually (for example with 'use ...') 1158 # -- OR -- 1159 # you can still specify it in PATH/TO/MODULES 1160 1161 # static dispatch that allows access to particular method ONLY 1162 MODULE::method 1163 # same as MODULE, but gives access to ONLY particular method, 1164 # so there is not much sense to use both MODULE and MODULE::method 1165 # for the same MODULE 1166 ); 1167 1168 In addition to this "SOAP::Lite" also supports an experimental syntax 1169 that allows you to bind a specific URL or SOAPAction to a CLASS/MODULE 1170 or object. 1171 1172 For example: 1173 1174 dispatch_with({ 1175 URI => MODULE, # 'http://www.soaplite.com/' => 'My::Class', 1176 SOAPAction => MODULE, # 'http://www.soaplite.com/method' => 'Another::Class', 1177 URI => object, # 'http://www.soaplite.com/obj' => My::Class->new, 1178 }) 1179 1180 "URI" is checked before "SOAPAction". You may use both the 1181 "dispatch_to()" and "dispatch_with()" methods in the same server, but 1182 note that "dispatch_with()" has a higher order of precedence. 1183 "dispatch_to()" will be checked only after "URI" and "SOAPAction" has 1184 been checked. 1185 1186 See also: EXAMPLE APACHE::REGISTRY USAGE, "SECURITY" 1187 1188 COMPRESSION 1189 "SOAP::Lite" provides you option to enable transparent compression over 1190 the wire. Compression can be enabled by specifying a threshold value (in 1191 the form of kilobytes) for compression on both the client and server 1192 sides: 1193 1194 *Note: Compression currently only works for HTTP based servers and 1195 clients.* 1196 1197 Client Code 1198 1199 print SOAP::Lite 1200 ->uri('http://localhost/My/Parameters') 1201 ->proxy('http://localhost/', options => {compress_threshold => 10000}) 1202 ->echo(1 x 10000) 1203 ->result; 1204 1205 Server Code 1206 1207 my $server = SOAP::Transport::HTTP::CGI 1208 ->dispatch_to('My::Parameters') 1209 ->options({compress_threshold => 10000}) 1210 ->handle; 1211 1212 For more information see COMPRESSION in HTTP::Transport. 1213 1214SECURITY 1215 For security reasons, the exisiting path for Perl modules (@INC) will be 1216 disabled once you have chosen dynamic deployment and specified your own 1217 "PATH/". If you wish to access other modules in your included package 1218 you have several options: 1219 1220 1 Switch to static linking: 1221 1222 use MODULE; 1223 $server->dispatch_to('MODULE'); 1224 1225 Which can also be useful when you want to import something specific 1226 from the deployed modules: 1227 1228 use MODULE qw(import_list); 1229 1230 2 Change "use" to "require". The path is only unavailable during the 1231 initialization phase. It is available once more during execution. 1232 Therefore, if you utilize "require" somewhere in your package, it 1233 will work. 1234 1235 3 Wrap "use" in an "eval" block: 1236 1237 eval 'use MODULE qw(import_list)'; die if $@; 1238 1239 4 Set your include path in your package and then specify "use". Don't 1240 forget to put @INC in a "BEGIN{}" block or it won't work. For 1241 example, 1242 1243 BEGIN { @INC = qw(my_directory); use MODULE } 1244 1245INTEROPERABILITY 1246 Microsoft .NET client with SOAP::Lite Server 1247 In order to use a .NET client with a SOAP::Lite server, be sure you use 1248 fully qualified names for your return values. For example: 1249 1250 return SOAP::Data->name('myname') 1251 ->type('string') 1252 ->uri($MY_NAMESPACE) 1253 ->value($output); 1254 1255 In addition see comment about default incoding in .NET Web Services 1256 below. 1257 1258 SOAP::Lite client with a .NET server 1259 If experiencing problems when using a SOAP::Lite client to call a .NET 1260 Web service, it is recommended you check, or adhere to all of the 1261 following recommendations: 1262 1263 Declare a proper soapAction in your call 1264 For example, use "on_action( sub { 1265 'http://www.myuri.com/WebService.aspx#someMethod'; } )". 1266 1267 Disable charset definition in Content-type header 1268 Some users have said that Microsoft .NET prefers the value of the 1269 Content-type header to be a mimetype exclusively, but SOAP::Lite 1270 specifies a character set in addition to the mimetype. This results 1271 in an error similar to: 1272 1273 Server found request content type to be 'text/xml; charset=utf-8', 1274 but expected 'text/xml' 1275 1276 To turn off this behavior specify use the following code: 1277 1278 use SOAP::Lite; 1279 $SOAP::Constants::DO_NOT_USE_CHARSET = 1; 1280 # The rest of your code 1281 1282 Use fully qualified name for method parameters 1283 For example, the following code is preferred: 1284 1285 SOAP::Data->name(Query => 'biztalk') 1286 ->uri('http://tempuri.org/') 1287 1288 As opposed to: 1289 1290 SOAP::Data->name('Query' => 'biztalk') 1291 1292 Place method in default namespace 1293 For example, the following code is preferred: 1294 1295 my $method = SOAP::Data->name('add') 1296 ->attr({xmlns => 'http://tempuri.org/'}); 1297 my @rc = $soap->call($method => @parms)->result; 1298 1299 As opposed to: 1300 1301 my @rc = $soap->call(add => @parms)->result; 1302 # -- OR -- 1303 my @rc = $soap->add(@parms)->result; 1304 1305 Disable use of explicit namespace prefixes 1306 Some user's have reported that .NET will simply not parse messages 1307 that use namespace prefixes on anything but SOAP elements 1308 themselves. For example, the following XML would not be parsed: 1309 1310 <SOAP-ENV:Envelope ...attributes skipped> 1311 <SOAP-ENV:Body> 1312 <namesp1:mymethod xmlns:namesp1="urn:MyURI" /> 1313 </SOAP-ENV:Body> 1314 </SOAP-ENV:Envelope> 1315 1316 SOAP::Lite allows users to disable the use of explicit namespaces 1317 through the "use_prefix()" method. For example, the following code: 1318 1319 $som = SOAP::Lite->uri('urn:MyURI') 1320 ->proxy($HOST) 1321 ->use_prefix(0) 1322 ->myMethod(); 1323 1324 Will result in the following XML, which is more pallatable by .NET: 1325 1326 <SOAP-ENV:Envelope ...attributes skipped> 1327 <SOAP-ENV:Body> 1328 <mymethod xmlns="urn:MyURI" /> 1329 </SOAP-ENV:Body> 1330 </SOAP-ENV:Envelope> 1331 1332 Modify your .NET server, if possible 1333 Stefan Pharies <stefanph@microsoft.com>: 1334 1335 SOAP::Lite uses the SOAP encoding (section 5 of the soap 1.1 spec), 1336 and the default for .NET Web Services is to use a literal encoding. 1337 So elements in the request are unqualified, but your service expects 1338 them to be qualified. .Net Web Services has a way for you to change 1339 the expected message format, which should allow you to get your 1340 interop working. At the top of your class in the asmx, add this 1341 attribute (for Beta 1): 1342 1343 [SoapService(Style=SoapServiceStyle.RPC)] 1344 1345 Another source said it might be this attribute (for Beta 2): 1346 1347 [SoapRpcService] 1348 1349 Full Web Service text may look like: 1350 1351 <%@ WebService Language="C#" Class="Test" %> 1352 using System; 1353 using System.Web.Services; 1354 using System.Xml.Serialization; 1355 1356 [SoapService(Style=SoapServiceStyle.RPC)] 1357 public class Test : WebService { 1358 [WebMethod] 1359 public int add(int a, int b) { 1360 return a + b; 1361 } 1362 } 1363 1364 Another example from Kirill Gavrylyuk <kirillg@microsoft.com>: 1365 1366 "You can insert [SoapRpcService()] attribute either on your class or 1367 on operation level". 1368 1369 <%@ WebService Language=CS class="DataType.StringTest"%> 1370 1371 namespace DataType { 1372 1373 using System; 1374 using System.Web.Services; 1375 using System.Web.Services.Protocols; 1376 using System.Web.Services.Description; 1377 1378 [SoapRpcService()] 1379 public class StringTest: WebService { 1380 [WebMethod] 1381 [SoapRpcMethod()] 1382 public string RetString(string x) { 1383 return(x); 1384 } 1385 } 1386 } 1387 1388 Example from Yann Christensen <yannc@microsoft.com>: 1389 1390 using System; 1391 using System.Web.Services; 1392 using System.Web.Services.Protocols; 1393 1394 namespace Currency { 1395 [WebService(Namespace="http://www.yourdomain.com/example")] 1396 [SoapRpcService] 1397 public class Exchange { 1398 [WebMethod] 1399 public double getRate(String country, String country2) { 1400 return 122.69; 1401 } 1402 } 1403 } 1404 1405 Special thanks goes to the following people for providing the above 1406 description and details on .NET interoperability issues: 1407 1408 Petr Janata <petr.janata@i.cz>, 1409 1410 Stefan Pharies <stefanph@microsoft.com>, 1411 1412 Brian Jepson <bjepson@jepstone.net>, and others 1413 1414TROUBLESHOOTING 1415 SOAP::Lite serializes "18373" as an integer, but I want it to be a 1416 string! 1417 SOAP::Lite guesses datatypes from the content provided, using a set 1418 of common-sense rules. These rules are not 100% reliable, though 1419 they fit for most data. 1420 1421 You may force the type by passing a SOAP::Data object with a type 1422 specified: 1423 1424 my $proxy = SOAP::Lite->proxy('http://www.example.org/soapservice'); 1425 my $som = $proxy->myMethod( 1426 SOAP::Data->name('foo')->value(12345)->type('string') 1427 ); 1428 1429 You may also change the precedence of the type-guessing rules. Note 1430 that this means fiddling with SOAP::Lite's internals - this may not 1431 work as expected in future versions. 1432 1433 The example above forces everything to be encoded as string (this is 1434 because the string test is normally last and allways returns true): 1435 1436 my @list = qw(-1 45 foo bar 3838); 1437 my $proxy = SOAP::Lite->uri($uri)->proxy($proxyUrl); 1438 my $lookup = $proxy->serializer->typelookup; 1439 $lookup->{string}->[0] = 0; 1440 $proxy->serializer->typelookup($lookup); 1441 $proxy->myMethod(\@list); 1442 1443 See SOAP::Serializer for more details. 1444 1445 "+autodispatch" doesn't work in Perl 5.8 1446 There is a bug in Perl 5.8's "UNIVERSAL::AUTOLOAD" functionality 1447 that prevents the "+autodispatch" functionality from working 1448 properly. The workaround is to use "dispatch_from" instead. Where 1449 you might normally do something like this: 1450 1451 use Some::Module; 1452 use SOAP::Lite +autodispatch => 1453 uri => 'urn:Foo' 1454 proxy => 'http://...'; 1455 1456 You would do something like this: 1457 1458 use SOAP::Lite dispatch_from(Some::Module) => 1459 uri => 'urn:Foo' 1460 proxy => 'http://...'; 1461 1462 Problems using SOAP::Lite's COM Interface 1463 1464 Can't call method "server" on undefined value 1465 You probably did not register Lite.dll using "regsvr32 Lite.dll" 1466 1467 Failed to load PerlCtrl Runtime 1468 It is likely that you have install Perl in two different 1469 locations and the location of ActiveState's Perl is not the 1470 first instance of Perl specified in your PATH. To rectify, 1471 rename the directory in which the non-ActiveState Perl is 1472 installed, or be sure the path to ActiveState's Perl is 1473 specified prior to any other instance of Perl in your PATH. 1474 1475 Dynamic libraries are not found 1476 If you are using the Apache web server, and you are seeing something 1477 like the following in your webserver log file: 1478 1479 Can't load '/usr/local/lib/perl5/site_perl/.../XML/Parser/Expat/Expat.so' 1480 for module XML::Parser::Expat: dynamic linker: /usr/local/bin/perl: 1481 libexpat.so.0 is NEEDED, but object does not exist at 1482 /usr/local/lib/perl5/.../DynaLoader.pm line 200. 1483 1484 Then try placing the following into your httpd.conf file and see if 1485 it fixes your problem. 1486 1487 <IfModule mod_env.c> 1488 PassEnv LD_LIBRARY_PATH 1489 </IfModule> 1490 1491 SOAP client reports "500 unexpected EOF before status line seen 1492 See "Apache is crashing with segfaults" 1493 1494 Apache is crashing with segfaults 1495 Using "SOAP::Lite" (or XML::Parser::Expat) in combination with 1496 mod_perl causes random segmentation faults in httpd processes. To 1497 fix, try configuring Apache with the following: 1498 1499 RULE_EXPAT=no 1500 1501 If you are using Apache 1.3.20 and later, try configuring Apache 1502 with the following option: 1503 1504 ./configure --disable-rule=EXPAT 1505 1506 See http://archive.covalent.net/modperl/2000/04/0185.xml for more 1507 details and lot of thanks to Robert Barta <rho@bigpond.net.au> for 1508 explaining this weird behavior. 1509 1510 If this doesn't address the problem, you may wish to try 1511 "-Uusemymalloc", or a similar option in order to instruct Perl to 1512 use the system's own "malloc". 1513 1514 Thanks to Tim Bunce <Tim.Bunce@pobox.com>. 1515 1516 CGI scripts do not work under Microsoft Internet Information Server 1517 (IIS) 1518 CGI scripts may not work under IIS unless scripts use the ".pl" 1519 extension, opposed to ".cgi". 1520 1521 Java SAX parser unable to parse message composed by SOAP::Lite 1522 In some cases SOAP messages created by "SOAP::Lite" may not be 1523 parsed properly by a SAX2/Java XML parser. This is due to a known 1524 bug in "org.xml.sax.helpers.ParserAdapter". This bug manifests 1525 itself when an attribute in an XML element occurs prior to the XML 1526 namespace declaration on which it depends. However, according to the 1527 XML specification, the order of these attributes is not significant. 1528 1529 http://www.megginson.com/SAX/index.html 1530 1531 Thanks to Steve Alpert (Steve_Alpert@idx.com) for pointing on it. 1532 1533PERFORMANCE 1534 Processing of XML encoded fragments 1535 "SOAP::Lite" is based on XML::Parser which is basically wrapper 1536 around James Clark's expat parser. Expat's behavior for parsing XML 1537 encoded string can affect processing messages that have lot of 1538 encoded entities, like XML fragments, encoded as strings. Providing 1539 low-level details, parser will call char() callback for every 1540 portion of processed stream, but individually for every processed 1541 entity or newline. It can lead to lot of calls and additional memory 1542 manager expenses even for small messages. By contrast, XML messages 1543 which are encoded as base64Binary, don't have this problem and 1544 difference in processing time can be significant. For XML encoded 1545 string that has about 20 lines and 30 tags, number of call could be 1546 about 100 instead of one for the same string encoded as 1547 base64Binary. 1548 1549 Since it is parser's feature there is NO fix for this behavior (let 1550 me know if you find one), especially because you need to parse 1551 message you already got (and you cannot control content of this 1552 message), however, if your are in charge for both ends of processing 1553 you can switch encoding to base64 on sender's side. It will 1554 definitely work with SOAP::Lite and it may work with other 1555 toolkits/implementations also, but obviously I cannot guarantee 1556 that. 1557 1558 If you want to encode specific string as base64, just do 1559 "SOAP::Data->type(base64 => $string)" either on client or on server 1560 side. If you want change behavior for specific instance of 1561 SOAP::Lite, you may subclass "SOAP::Serializer", override 1562 "as_string()" method that is responsible for string encoding (take a 1563 look into "as_base64Binary()") and specify new serializer class for 1564 your SOAP::Lite object with: 1565 1566 my $soap = new SOAP::Lite 1567 serializer => My::Serializer->new, 1568 ..... other parameters 1569 1570 or on server side: 1571 1572 my $server = new SOAP::Transport::HTTP::Daemon # or any other server 1573 serializer => My::Serializer->new, 1574 ..... other parameters 1575 1576 If you want to change this behavior for all instances of SOAP::Lite, 1577 just substitute "as_string()" method with "as_base64Binary()" 1578 somewhere in your code after "use SOAP::Lite" and before actual 1579 processing/sending: 1580 1581 *SOAP::Serializer::as_string = \&SOAP::XMLSchema2001::Serializer::as_base64Binary; 1582 1583 Be warned that last two methods will affect all strings and convert 1584 them into base64 encoded. It doesn't make any difference for 1585 SOAP::Lite, but it may make a difference for other toolkits. 1586 1587BUGS AND LIMITATIONS 1588 * No support for multidimensional, partially transmitted and sparse 1589 arrays (however arrays of arrays are supported, as well as any other 1590 data structures, and you can add your own implementation with 1591 SOAP::Data). 1592 1593 * Limited support for WSDL schema. 1594 1595 * XML::Parser::Lite relies on Unicode support in Perl and doesn't do 1596 entity decoding. 1597 1598 * Limited support for mustUnderstand and Actor attributes. 1599 1600PLATFORM SPECIFICS 1601 MacOS 1602 Information about XML::Parser for MacPerl could be found here: 1603 1604 http://bumppo.net/lists/macperl-modules/1999/07/msg00047.html 1605 1606 Compiled XML::Parser for MacOS could be found here: 1607 1608 http://www.perl.com/CPAN-local/authors/id/A/AS/ASANDSTRM/XML-Parser- 1609 2.27-bin-1-MacOS.tgz 1610 1611RELATED MODULES 1612 Transport Modules 1613 SOAP::Lite allows one to add support for additional transport protocols, 1614 or server handlers, via separate modules implementing the 1615 SOAP::Transport::* interface. The following modules are available from 1616 CPAN: 1617 1618 * SOAP-Transport-HTTP-Nginx 1619 1620 SOAP::Transport::HTTP::Nginx provides a transport module for nginx 1621 (<http://nginx.net/>) 1622 1623AVAILABILITY 1624 You can download the latest version SOAP::Lite for Unix or SOAP::Lite 1625 for Win32 from the following sources: 1626 1627 * CPAN: http://search.cpan.org/search?dist=SOAP-Lite 1628 1629 You are welcome to send e-mail to the maintainers of SOAP::Lite with 1630 your comments, suggestions, bug reports and complaints. 1631 1632ACKNOWLEDGEMENTS 1633 Special thanks to Randy J. Ray, author of *Programming Web Services with 1634 Perl*, who has contributed greatly to the documentation effort of 1635 SOAP::Lite. 1636 1637 Special thanks to O'Reilly publishing which has graciously allowed 1638 SOAP::Lite to republish and redistribute the SOAP::Lite reference manual 1639 found in Appendix B of *Programming Web Services with Perl*. 1640 1641 And special gratitude to all the developers who have contributed 1642 patches, ideas, time, energy, and help in a million different forms to 1643 the development of this software. 1644 1645HACKING 1646 Latest development takes place on GitHub.com. Come on by and fork it. 1647 1648 git@github.com:redhotpenguin/soaplite.git 1649 1650 Also see the HACKING file. 1651 1652 Actively recruiting maintainers for this module. Come and get it on! 1653 1654REPORTING BUGS 1655 Please use rt.cpan.org or github to report bugs. Pull requests are 1656 preferred. 1657 1658COPYRIGHT 1659 Copyright (C) 2000-2007 Paul Kulchenko. All rights reserved. 1660 1661 Copyright (C) 2007-2008 Martin Kutter 1662 1663 Copyright (C) 2013 Fred Moyer 1664 1665LICENSE 1666 This library is free software; you can redistribute it and/or modify it 1667 under the same terms as Perl itself. 1668 1669 This text and all associated documentation for this library is made 1670 available under the Creative Commons Attribution-NoDerivs 2.0 license. 1671 http://creativecommons.org/licenses/by-nd/2.0/ 1672 1673AUTHORS 1674 Paul Kulchenko (paulclinger@yahoo.com) 1675 1676 Randy J. Ray (rjray@blackperl.com) 1677 1678 Byrne Reese (byrne@majordojo.com) 1679 1680 Martin Kutter (martin.kutter@fen-net.de) 1681 1682 Fred Moyer (fred@redhotpenguin.com) 1683 1684