1SOAP::Transport(3) User Contributed Perl Documentation SOAP::Transport(3)
2
3
4
6 SOAP::Transport - an abstract class extended by more specialized
7 transport modules
8
10 Objects of the SOAP::Transport class manage two roles: they manage both
11 the parameters related to transport as set through the containing
12 SOAP::Lite object, and they abstract the selection and loading of an
13 appropriate transport module. This is done with an AUTOLOAD function
14 within the class that intercepts all methods beyond the two defined
15 next and reroutes them to the underlying transport implementation code.
16
18 new
19 $trans = SOAP::Transport->new;
20
21 This is the constructor, which isn't usually called by an
22 application directly. An application can use this to create a fresh
23 new SOAP::Transport object, which may be installed using the
24 SOAP::Lite->transport method defined earlier. No arguments are
25 recognized.
26
27 proxy(optional URL string)
28 $trans->proxy('http://www.blackperl.com/SOAP');
29
30 Gets or sets the proxy (endpoint). This method must be called
31 before any other methods are called. The proper transport code is
32 loaded based on the scheme specified by the URL itself (http,
33 jabber, etc.). Until this method is called the first time with a
34 URL string, the underlying code has yet to be loaded, and the
35 methods aren't available. When getting the current proxy (calling
36 with no parameters), the returned value is a reference to the
37 client object created from the protocol class that matched the
38 endpoint, not the endpoint itself.
39
41 Because the bulk of the work is done within the "SOAP::Lite" module
42 itself, many of the transport-level modules are very simple in their
43 implementations. Transport modules are expected to define both client
44 and server classes within their files. If a module defines only one of
45 the types, it is assumed that the transport protocol itself supports
46 only that side of the conversation. An example is SOAP::Transport::FTP,
47 which provides only a "SOAP::Transport::FTP::Client" class.
48
49 "SOAP::Transport::FTP" - Client class only
50
51 "SOAP::Transport::HTTP" - Client, and server classes for CGI, FCGI,
52 Daemon and mod_perl
53
54 "SOAP::Transport::IO" - Server class only
55
56 "SOAP::Transport::JABBER" - Server and Client classes
57
58 "SOAP::Transport::LOCAL" - Client class only
59
60 "SOAP::Transport::MAILTO" - Client class only
61
62 "SOAP::Transport::MQ" - Server and Client classes
63
64 "SOAP::Transport::POP3" - Server class only
65
66 "SOAP::Transport::TCP" - Server and Client classes
67
68 METHODS
69 Each SOAP::Transport sub-class is expected to define (or inherit, if it
70 is subclassing another transport class) at least two methods. Any newly
71 developed transport classes are also expected to adhere to this
72 interface. Clients are expected to implement the "new" and
73 "send_receive" methods, and servers are expected to implement the "new"
74 and "handle" methods. Here they are:
75
76 new(optional key/value pairs)
77 $object = $class->new(%params);
78
79 Creates a new object instance and returns it. Like the constructors
80 for both "SOAP::Lite" and SOAP::Server classes, all arguments
81 passed in are treated as key/value pairs, where the key is expected
82 to be one of the methods the class supports, and the value is the
83 argument (or list reference of arguments) to the method.
84
85 send_receive(key/value pairs)
86 $client->send_recieve(%hash_table);
87
88 (Required for client classes only) When the SOAP::Lite objects
89 attempt to send out requests, the means for doing so is to attempt
90 to call this method on the object held within the SOAP::Transport
91 object contained within the client itself. All clients are expected
92 to provide this, and the call to this method always passes four
93 values for the hash keys:
94
95 action
96 The URI specifying the action being performed, usually the
97 result from the on_action hook on the client object.
98
99 encoding
100 The URI of the encoding scheme that governs the message being
101 sent.
102
103 endpoint
104 The URI specifying the endpoint to which the message is being
105 sent.
106
107 envelope
108 The XML content of the message to be sent. It is generally the
109 return value of the envelope method from the SOAP::Serializer
110 object instance that the client object maintains.
111
112 parts
113 Attachments to add to the request. Currently this only supports
114 an array of MIME::Entity objects, but in theory could support
115 attachments of any format.
116
117 handle
118 $server->handle;
119
120 (Required for server classes only.) This method is the central
121 point for the various server classes to provide an interface to
122 handling requests. The exact set and nature of parameters generally
123 varies based on the classes themselves.
124
125 SOAP::Transport::HTTP
126 The most commonly used transport module is the HTTP implementation.
127 This is loaded whenever an endpoint is given that starts with the
128 characters, http:// or https://. This is also the most involved of the
129 transport modules, defining not only a client class but several
130 different server classes as well.
131
132 HTTP PROXY SETTINGS
133
134 Because "SOAP::Client" inherits from "LWP::UserAgent", you can use any
135 of "LWP::UserAgent"'s proxy settings. For example:
136
137 SOAP::Lite->proxy("http://endpoint.server/",
138 proxy => ["http" => "http://my.proxy.server"]);
139
140 or
141
142 $soap->transport->proxy("http" => "http://my.proxy.server");
143
144 The above code samples should specify a proxy server for you. And
145 should you use "HTTP_proxy_user" and "HTTP_proxy_pass" for proxy
146 authorization, "SOAP::Lite" will handle it properly.
147
148 HTTP BASIC AUTHENTICATION
149
150 HTTP Basic authentication is accomplished by overriding the
151 get_basic_credentials subroutine in "LWP::UserAgent" (which
152 "SOAP::Transport::HTTP::Client" is a subclass):
153
154 BEGIN {
155 sub SOAP::Transport::HTTP::Client::get_basic_credentials {
156 return 'username' => 'password';
157 }
158 }
159
160 COOKIE-BASED AUTHENTICATION
161
162 use HTTP::Cookies;
163 my $cookies = HTTP::Cookies->new(ignore_discard => 1);
164 # you may also add 'file' if you want to keep them between sessions
165 my $soap = SOAP::Lite->proxy('http://localhost/');
166 $soap->transport->cookie_jar($cookies);
167
168 Or, alternatively, you can do the above on a single line:
169
170 $soap->proxy('http://localhost/',
171 cookie_jar => HTTP::Cookies->new(ignore_discard => 1));
172
173 Cookies will be taken from the response and provided to the request.
174 You may access and manipulate cookies received, as well as add cookies
175 of your own by using the "HTTP::Cookies" interfaces.
176
177 SSL CERTIFICATE AUTHENTICATION
178
179 The default SSL implementation for the HTTP client library
180 LWP::UserAgent used by SOAP::Lite is IO::Socket::SSL.
181
182 To enable certificate based authentication, you'll have to pass your
183 certificate and key as additional options to the proxy() method like
184 this:
185
186 $soap->proxy( $url, ssl_opts => {
187 SSL_cert_file => 'client-cert.pem',
188 SSL_key_file => 'client-key.pem'
189 });
190
191 Or you can set them later like this:
192
193 $soap->transport->ssl_opts(
194 SSL_cert_file => 'client-cert.pem',
195 SSL_key_file => 'client-key.pem'
196 );
197
198 If you're using Crypt::SSLeay, the following applies:
199
200 To get certificate authentication working you need to set three
201 environment variables: "HTTPS_CERT_FILE", "HTTPS_KEY_FILE", and
202 optionally "HTTPS_CERT_PASS". This can be done either through the
203 command line, or directly within your Perl script using the $ENV
204 variable:
205
206 $ENV{HTTPS_CERT_FILE} = 'client-cert.pem';
207 $ENV{HTTPS_KEY_FILE} = 'client-key.pem';
208
209 These settings are referenced by "Crypt::SSLeay". Other options (e.g.
210 CA peer verification) can be specified in a similar way. See
211 Crypt::SSLeay documentation for more information.
212
213 Please note that you probably should not be using Crypt::SSLeay because
214 it does not perform hostname verification; LWP::UserAgent uses
215 IO::Socket::SSL by default. See also
216 <https://metacpan.org/pod/Crypt::SSLeay#DO-YOU-NEED-Crypt::SSLeay>.
217
218 Those who would like to use encrypted keys may find the following
219 thread in the SOAP::Lite newsgroup helpful:
220
221 http://groups.yahoo.com/group/soaplite/message/729
222
223 COMPRESSION
224
225 SOAP::Lite provides you with the option for enabling compression over
226 the wire using HTTP only in both the server and client contexts,
227 provided that you have Compress::Zlib installed. Compression and
228 decompression is done transparently to your application.
229
230 A server will respond with an encoded/compressed message only if the
231 client has asserted that it can accept it (indicated by client sending
232 an "Accept-Encoding" HTTP header with a 'deflate' or '*' value).
233
234 "SOAP::Lite" clients all have fallback logic implemented so that if a
235 server doesn't understand the specified encoding (i.e. "Content-
236 Encoding: deflate") and returns the proper HTTP status code (415 NOT
237 ACCEPTABLE), the client will repeat the request without using
238 encoding/compression. The client will then store this server in a per-
239 session cache, so that all subsequent requests to that server will be
240 transmitted without encoding.
241
242 Compression is enabled on the client side by specifying the
243 "compress_threshold" option, and if the size of the current request
244 exceeds that threshold.
245
246 Client Code Sample
247
248 print SOAP::Lite
249 ->uri('http://localhost/My/Parameters')
250 ->proxy('http://localhost/', options => {compress_threshold => 10000})
251 ->echo(1 x 10000)
252 ->result;
253
254 Servers will respond with a compressed message if the
255 "compress_threshold" option has been specified, if the size of the
256 current response exceeds that threshold, and if the calling client
257 transmitted the proper "Accept-Encoding" HTTP Header.
258
259 Server Code Sample
260
261 my $server = SOAP::Transport::HTTP::CGI
262 ->dispatch_to('My::Parameters')
263 ->options({compress_threshold => 10000})
264 ->handle;
265
266 See also: Compress::Zlib
267
268 SOAP::Transport::HTTP::Client
269
270 Inherits from: SOAP::Client, LWP::UserAgent (from the LWP package).
271
272 With this class, clients are able to use HTTP for sending messages.
273 This class provides just the basic new and send_receive methods.
274 Objects of this class understand the compress_threshold option and use
275 it if the server being communicated to also understands it.
276
277 CHANGING THE DEFAULT USERAGENT CLASS
278
279 By default, "SOAP::Transport::HTTP::Client" extends "LWP::UserAgent".
280 But under some circumstances, a user may wish to change the default
281 UserAgent class with their in order to better handle persist
282 connections, or to "LWP::UserAgent::ProxyAny", for example, which has
283 better Win32/Internet Explorer interoperability.
284
285 One can use the code below as an example of how to change the default
286 UserAgent class.
287
288 use SOAP::Lite;
289 use SOAP::Transport::HTTP;
290 $SOAP::Transport::HTTP::Client::USERAGENT_CLASS = "My::UserAgent";
291 my $client = SOAP::Lite->proxy(..)->uri(..);
292 my $som = $client->myMethod();
293
294 There is one caveat, however. The UserAgent class you use, MUST also be
295 a subclass of "LWP::UserAgent". If it is not, then "SOAP::Lite" will
296 issue the following error: "Could not load UserAgent class <USERAGENT
297 CLASS>."
298
299 HTTP-KEEP-ALIVE, TIMEOUTS, AND MORE
300
301 Because "SOAP::Transport::HTTP::Client" extends "LWP::UserAgent", all
302 methods available "LWP::UserAgent" are also available to your SOAP
303 Clients. For example, using "LWP::UserAgent" HTTP keep alive's are
304 accomplished using the following code:
305
306 my $ua = LWP::UserAgent->new(
307 keep_alive => 1,
308 timeout => 30
309 );
310
311 Therefore, the same initialization parameters you would pass to
312 "LWP::UserAgent" can also be passed to your SOAP::Lite client's "proxy"
313 subroutine like so:
314
315 my $soap = SOAP::Lite
316 ->uri($uri)
317 ->proxy($proxyUrl,
318 timeout => 30,
319 keep_alive => 1,
320 );
321
322 This is true for all initialization parameters and methods of
323 "LWP::UserAgent".
324
325 METHODS
326
327 http_request
328 This method gives you access to a prototype of the HTTP Request
329 object that will be transmitted to a SOAP::Server. The actual
330 request used is a copy of that object.
331
332 Do not use this method for anything else than setting prototypic
333 behaviour for the client object.
334
335 http_response
336 This method gives you access to the HTTP Response object that will
337 be, or was transmitted to a SOAP Server. It returns a
338 HTTP::Response object.
339
340 SOAP::Transport::HTTP::Server
341
342 Inherits from: SOAP::Server.
343
344 This is the most basic of the HTTP server implementations. It provides
345 the
346 basic methods, new and handle. The handle method's behavior is defined
347 here,
348 along with other methods specific to this class. The role of this
349 class is
350 primarily to act as a superclass for the other HTTP-based server
351 classes.
352
353 handle
354 $server->handle;
355
356 Expects the request method to have been used to associate a
357 HTTP::Request object with the server object prior to being called.
358 This method retrieves that object reference to get at the request
359 being handled.
360
361 request(optional value)
362 $server->request($req_object)
363
364 Gets or sets the HTTP::Request object reference that the server
365 will process within the handle method.
366
367 response(optional value)
368 $server->response(HTTP::Response->new(...));
369
370 Gets or sets the HTTP::Response object reference that the server
371 has prepared for sending back to the client.
372
373 make_response(code, body)
374 $server->make_response(200, $body_xml);
375
376 Constructs and returns an object of the HTTP::Response class, using
377 the response code and content provided.
378
379 make_fault(fault arguments)
380 $server->response($server->make_fault(@data));
381
382 Creates a HTTP::Response object reference using a predefined HTTP
383 response code to signify that a fault has occurred. The arguments
384 are the same as those for the make_fault method of the SOAP::Server
385 class.
386
387 product_tokens
388 This method takes no arguments and simply returns a string
389 identifying the elements of the server class itself. It is similar
390 to the product_tokens methods in the HTTP::Daemon and Apache
391 classes.
392
393 SOAP::Transport::HTTP::CGI
394
395 Inherits from: SOAP::Transport::HTTP::Server.
396
397 This class is a direct subclass of SOAP::Transport::HTTP::Server and
398 defines no additional methods. It includes logic in its implementation
399 of the handle method that deals with the request headers and parameters
400 specific to a CGI environment.
401
402 EXAMPLE CGI
403
404 The following code sample is a CGI based Web Service that converts
405 celsius to fahrenheit:
406
407 #!/usr/bin/perl
408 use SOAP::Transport::HTTP;
409 SOAP::Transport::HTTP::CGI
410 ->dispatch_to('C2FService')
411 ->handle;
412 BEGIN {
413 package C2FService;
414 use vars qw(@ISA);
415 @ISA = qw(Exporter SOAP::Server::Parameters);
416 use SOAP::Lite;
417 sub c2f {
418 my $self = shift;
419 my $envelope = pop;
420 my $temp = $envelope->dataof("//c2f/temperature");
421 return SOAP::Data->name('convertedTemp' => (((9/5)*($temp->value)) + 32));
422 }
423 }
424
425 EXAMPLE APACHE::REGISTRY USAGE
426
427 Using a strictly CGI based Web Service has certain performance
428 drawbacks. Running the same CGI under the Apache::Registery system has
429 certain performance gains.
430
431 httpd.conf
432
433 Alias /mod_perl/ "/Your/Path/To/Deployed/Modules"
434 <Location /mod_perl>
435 SetHandler perl-script
436 PerlHandler Apache::Registry
437 PerlSendHeader On
438 Options +ExecCGI
439 </Location>
440
441 soap.cgi
442
443 use SOAP::Transport::HTTP;
444
445 SOAP::Transport::HTTP::CGI
446 ->dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method')
447 ->handle;
448
449 WARNING: Dynamic deployments with "Apache::Registry" will fail because
450 the module will be only loaded dynamically the first time. Subsequent
451 calls will produce "denied access" errors because once the module is
452 already in memory "SOAP::Lite" will bypass dynamic deployment. To work
453 around this, simply specify both the full PATH and MODULE name in
454 dispatch_to() and the module will be loaded dynamically, but will then
455 work as if under static deployment. See examples/server/soap.mod_cgi as
456 an example.
457
458 SOAP::Transport::HTTP::Daemon
459
460 Inherits from: SOAP::Transport::HTTP::Server.
461
462 The SOAP::Transport::HTTP::Daemon class encapsulates a reference to an
463 object of the HTTP::Daemon class (from the LWP package). The class
464 catches methods that aren't provided locally or by the superclass and
465 attempts to call them on the HTTP::Daemon object. Thus, all methods
466 defined in the documentation for that class are available to this class
467 as well. Any that conflict with methods in
468 SOAP::Transport::HTTP::Server (such as product_tokens) go to the
469 superclass. Additionally, the behavior of the handle method is specific
470 to this class:
471
472 handle
473 When invoked, this method enters into the typical accept loop in
474 which it waits for a request on the socket that the daemon object
475 maintains and deals with the content of the request. When all
476 requests from the connection returned by the accept method of the
477 HTTP::Daemon object have been processed, this method returns.
478
479 REUSING SOCKETS ON RESTART
480
481 Often when implementing an HTTP daemon, sockets will get tied up when
482 you try to restart the daemon server. This prevents the server from
483 restarting. Often users will see an error like "Cannot start server:
484 port already in use." To circumvent this, instruct SOAP::Lite to reuse
485 open sockets using "Reuse => 1":
486
487 my $daemon = SOAP::Transport::HTTP::Daemon
488 -> new (LocalPort => 80000, Reuse => 1)
489
490 EXAMPLE DAEMON SERVER
491
492 use SOAP::Transport::HTTP;
493 # change LocalPort to 81 if you want to test it with soapmark.pl
494 my $daemon = SOAP::Transport::HTTP::Daemon
495 -> new (LocalAddr => 'localhost', LocalPort => 80)
496 # specify list of objects-by-reference here
497 -> objects_by_reference(qw(My::PersistentIterator My::SessionIterator My::Chat))
498 # specify path to My/Examples.pm here
499 -> dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method')
500 ;
501 print "Contact to SOAP server at ", $daemon->url, "\n";
502 $daemon->handle;
503
504 SOAP::Transport::HTTP::Apache
505
506 Inherits from: SOAP::Transport::HTTP::Server.
507
508 This class provides an integration of the SOAP::Server base class with
509 the mod_perl extension for Apache. To work as a location handler, the
510 package provides a method called handler, for which handle is made an
511 alias. The new method isn't functionally different from the superclass.
512 Here are the other methods provided by this class:
513
514 handler(Apache request)
515 $server->handler($r)
516
517 Defines the basis for a location handler in the mod_perl fashion.
518 The method expects an Apache request object as the parameter, from
519 which it pulls the body of the request and calls the superclass
520 handle method.
521
522 Note that in this class, the local method named handle is aliased
523 to this method.
524
525 configure(Apache request)
526 $server->configure(Apache->request);
527
528 Per-location configuration information can be provided to the
529 server object using the Apache DirConfig directive and calling this
530 method on the object itself. When invoked, the method reads the
531 directory configuration information from Apache and looks for lines
532 of the form:
533
534 method => param
535
536 Each line that matches the pattern is regarded as a potential
537 method to call on the server object, with the remaining token taken
538 as the parameter to the method. Methods that take hash references
539 as arguments may be specified as:
540
541 method => key => param, key => param
542
543 The key/value pairs will be made into a hash reference on demand.
544 If the server object doesn't recognize the named method as valid,
545 it ignores the line.
546
547 EXAMPLE APACHE MOD_PERL SERVER
548
549 See examples/server/Apache.pm and Apache::SOAP for more information.
550
551 httpd.conf
552
553 <Location /soap>
554 SetHandler perl-script
555 PerlHandler SOAP::Apache
556 PerlSetVar options "compress_threshold => 10000"
557 </Location>
558
559 SOAP::Apache.pm
560
561 package SOAP::Apache;
562 use SOAP::Transport::HTTP;
563 my $server = SOAP::Transport::HTTP::Apache
564 ->dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method');
565 sub handler { $server->handler(@_) }
566 1;
567
568 See also Apache::SOAP.
569
570 SOAP::Transport::HTTP::FCGI
571
572 Inherits from: SOAP::Transport::HTTP::CGI.
573
574 This is an extension of the SOAP::Transport::HTTP::CGI that implements
575 the differences needed for the FastCGI protocol. None of the methods
576 are functionally different.
577
578 SOAP::Transport::IO
579 The SOAP::Transport::IO-based class allows for a sort of I/O proxying
580 by allowing the application to configure what files or filehandles are
581 used. This module supplies only a server class.
582
583 SOAP::Transport::IO::Server
584
585 Inherits from: SOAP::Server.
586
587 The server class defined here inherits all methods from SOAP::Server,
588 and adds two additional methods specific to the nature of the class:
589
590 in
591 $server->in(IO::File->new($file));
592
593 Gets or sets the current filehandle being used as the input source.
594
595 out
596 $server->out(\*STDERR);
597
598 Gets or sets the filehandle being used as the output destination.
599
600 SOAP::Transport::LOCAL
601 The SOAP::Transport::LOCAL module is designed to provide a no-transport
602 client class for tracing and debugging communications traffic. It links
603 SOAP::Client and SOAP::Server so that the same object that "sends" the
604 request also "receives" it.
605
606 SOAP::Transport::LOCAL::Client
607
608 Inherits from: SOAP::Client, SOAP::Server. The implementations of the
609 new and send_receive methods aren't noticeably different in their
610 interface. Their behavior warrants description, however:
611
612 new When the constructor creates a new object of this class, it sets up
613 a few things beyond the usual SOAP::Client layout. The is_success
614 method is set to a default value of 1. The dispatch_to method
615 inherited from SOAP::Server is called with the current value of the
616 global array @INC, allowing the client to call any methods that can
617 be found in the current valid search path. And as with most of the
618 constructors in this module, the optional key/value pairs are
619 treated as method names and parameters.
620
621 send_receive
622 The implementation of this method simply passes the envelope
623 portion of the input data to the handle method of SOAP::Server.
624 While no network traffic results (directly) from this, it allows
625 for debug signals to be sent through the SOAP::Trace facility.
626
627 SOAP::Transport::MAILTO
628 This transport class manages SMTP-based sending of messages from a
629 client perspective. It doesn't provide a server class. The class gets
630 selected when a client object passes a URI to proxy or endpoint that
631 starts with the characters, mailto:.
632
633 SOAP::Transport::MAILTO::Client
634
635 Inherits from: SOAP::Client.
636
637 The client class for this protocol doesn't define any new methods. The
638 constructor functions in the same style as the others class
639 constructors. The functionality of the send_receive method is slightly
640 different from other classes, however.
641
642 When invoked, the send_receive method uses the MIME::Lite package to
643 encapsulate and transmit the message. Because mail messages are one-way
644 communications (the reply being a separate process), there is no
645 response message to be returned by the method. Instead, all the status-
646 related attributes (code, message, status, is_success) are set, and no
647 value is explicitly returned.
648
649 SOAP::Transport::POP3
650 POP3 support is limited to a server implementation. Just as the MAILTO
651 class detailed earlier operates by sending requests without expecting
652 to process a response, the server described here accepts request
653 messages and dispatches them without regard for sending a response
654 other than that which POP3 defines for successful delivery of a
655 message.
656
657 SOAP::Transport::POP3::Server
658
659 Inherits from: SOAP::Server.
660
661 The new method of this class creates an object of the Net::POP3 class
662 to use internally for polling a specified POP3 server for incoming
663 messages. When an object of this class is created, it expects an
664 endpoint to be specified with a URI that begins with the characters
665 pop:// and includes user ID and password information as well as the
666 hostname itself.
667
668 The handle method takes the messages present in the remote mailbox and
669 passes them (one at a time) to the superclass handle method. Each
670 message is deleted after being routed. All messages in the POP3 mailbox
671 are presumed to be SOAP messages.
672
673 Methods for the Net::POP3 object are detected and properly routed,
674 allowing operations such as $server->ping( ).
675
676 This means that the endpoint string doesn't need to provide the user ID
677 and password because the login method from the POP3 API may be used
678 directly.
679
681 Special thanks to O'Reilly publishing which has graciously allowed
682 SOAP::Lite to republish and redistribute large excerpts from
683 Programming Web Services with Perl, mainly the SOAP::Lite reference
684 found in Appendix B.
685
687 Copyright (C) 2000-2004 Paul Kulchenko. All rights reserved.
688
689 This library is free software; you can redistribute it and/or modify it
690 under the same terms as Perl itself.
691
693 Paul Kulchenko (paulclinger@yahoo.com)
694
695 Randy J. Ray (rjray@blackperl.com)
696
697 Byrne Reese (byrne@majordojo.com)
698
699
700
701perl v5.36.0 2023-01-20 SOAP::Transport(3)