import SOAP-WSDL 2.00_08 from CPAN
git-cpan-module: SOAP-WSDL git-cpan-version: 2.00_08 git-cpan-authorid: MKUTTER git-cpan-file: authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_08.tar.gz
This commit is contained in:
committed by
Michael G. Schwern
parent
40e0e67e84
commit
312f3d6bbd
+135
-50
@@ -2,26 +2,45 @@ package SOAP::WSDL::Client;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Carp;
|
||||
use Scalar::Util qw(blessed);
|
||||
use SOAP::WSDL::Envelope;
|
||||
use SOAP::Lite;
|
||||
|
||||
use Class::Std::Storable;
|
||||
use LWP::UserAgent;
|
||||
use HTTP::Request;
|
||||
use Scalar::Util qw(blessed);
|
||||
|
||||
use SOAP::WSDL::Envelope;
|
||||
use SOAP::WSDL::Expat::MessageParser;
|
||||
use SOAP::WSDL::SOAP::Typelib::Fault11;
|
||||
|
||||
# Package globals for speed...
|
||||
my $PARSER;
|
||||
my $MESSAGE_HANDLER;
|
||||
|
||||
|
||||
my %class_resolver_of :ATTR(:name<class_resolver> :default<()>);
|
||||
my %no_dispatch_of :ATTR(:name<no_dispatch> :default<()>);
|
||||
my %outputxml_of :ATTR(:name<outputxml> :default<()>);
|
||||
my %proxy_of :ATTR(:name<proxy> :default<()>);
|
||||
|
||||
my %fault_class_of :ATTR(:name<fault_class> :default<SOAP::WSDL::SOAP::Typelib::Fault11>);
|
||||
my %trace_of :ATTR(:set<trace> :init_arg<trace> :default<()> );
|
||||
my %on_action_of :ATTR(:name<on_action> :default<()>);
|
||||
my %content_type_of :ATTR(:name<content_type> :default<text/xml; charset=utf8>);
|
||||
|
||||
#/#trick editors
|
||||
|
||||
# TODO remove when preparing 2.01
|
||||
sub outputtree { warn 'outputtree is deprecated and'
|
||||
. 'will be removed before reaching v2.01 !' }
|
||||
|
||||
|
||||
sub get_trace {
|
||||
my $ident = ident $_[0];
|
||||
return $trace_of{ $ident }
|
||||
? ref $trace_of{ $ident } eq 'CODE'
|
||||
? $trace_of{ $ident }
|
||||
: sub { warn @_ }
|
||||
: ()
|
||||
}
|
||||
|
||||
# Mimic SOAP::Lite's behaviour for getter/setter routines
|
||||
SUBFACTORY: {
|
||||
no strict qw(refs);
|
||||
for (qw(class_resolver no_dispatch outputxml proxy)) {
|
||||
@@ -43,83 +62,84 @@ BEGIN {
|
||||
|
||||
sub call {
|
||||
my $self = shift;
|
||||
my $method = shift;
|
||||
my $data = ref $_[0] ? $_[0] : { @_ };
|
||||
my $content = q{};
|
||||
my ($envelope, $soap_action);
|
||||
my $method = shift;
|
||||
my $ident = ident $self;
|
||||
my $data = ref $_[0]
|
||||
? $_[0]
|
||||
: (@_>1)
|
||||
? { @_ }
|
||||
: $_[0];
|
||||
|
||||
my $soap_action;
|
||||
my $trace_sub = $self->get_trace();
|
||||
my $envelope = SOAP::WSDL::Envelope->serialize( $method, $data );
|
||||
|
||||
if (blessed $data
|
||||
&& $data->isa('SOAP::WSDL::XSD::Typelib::Builtin::anyType'))
|
||||
{
|
||||
$envelope = SOAP::WSDL::Envelope->serialize( $method, $data );
|
||||
# TODO replace by something derived from binding - this is just a
|
||||
# workaround...
|
||||
$soap_action = join '/', $data->get_xmlns(), $method;
|
||||
}
|
||||
else {
|
||||
$envelope = SOAP::WSDL::Envelope->serialize( $method, $data );
|
||||
# $soap_action = $self->on_action( $method );
|
||||
}
|
||||
|
||||
# TODO add something like SOAP::Lite's on_action mechanism
|
||||
$soap_action = $on_action_of{$ident}->( $self, $method ) if ($on_action_of{$ident});
|
||||
}
|
||||
|
||||
return $envelope if $self->no_dispatch();
|
||||
|
||||
# warn $envelope;
|
||||
|
||||
# get response via transport layer
|
||||
# TODO remove dependency from SOAP::Lite and use a
|
||||
# SAX-based filter using XML::LibXML to get the
|
||||
# result.
|
||||
# Filter should have the following methods:
|
||||
# maybe we should return a result with the following methods:
|
||||
# - result: returns the result of the call (like SOAP::Lite, but as
|
||||
# perl data structure)
|
||||
# object tree)
|
||||
# - header: returns the content of the SOAP header
|
||||
# - fault: returns the result of the call if a SOAP fault is sent back
|
||||
# by the server. Retuns undef (nothing) if the call has been
|
||||
# processed without errors.
|
||||
my $soap = SOAP::Lite->new()->proxy( $self->get_proxy() );
|
||||
my $response = $soap->transport->send_receive(
|
||||
context => $self, # this is provided for context
|
||||
endpoint => $soap->endpoint(),
|
||||
action => $soap_action, # SOAPAction, should be from binding
|
||||
envelope => $envelope, # use custom content
|
||||
);
|
||||
|
||||
# warn 'Received ' . length($response) . ' bytes of content';
|
||||
return $response if ($self->outputxml() );
|
||||
my $ua = LWP::UserAgent->new();
|
||||
my $request = HTTP::Request->new( 'POST',
|
||||
$self->get_proxy(),
|
||||
[ 'Content-Type', $content_type_of{ $ident },
|
||||
'Content-Length', length($envelope),
|
||||
'SOAPAction', $soap_action,
|
||||
],
|
||||
$envelope );
|
||||
|
||||
|
||||
$trace_sub->( $request->as_string() ) if $trace_of{ $ident }; # if for speed
|
||||
my $response = $ua->request( $request );
|
||||
$trace_sub->( $response->as_string() ) if $trace_of{ $ident }; # if for speed
|
||||
|
||||
return $response->content() if ($self->outputxml() );
|
||||
|
||||
$PARSER->class_resolver( $self->get_class_resolver() );
|
||||
|
||||
# if we had no success (Transport layer error status code)
|
||||
# or if transport layer failed
|
||||
if (! $soap->transport->is_success() ) {
|
||||
# or if transport layer failed
|
||||
if ($response->code() != 200) {
|
||||
# Try deserializing response - there may be some
|
||||
if ($response) {
|
||||
eval { $PARSER->parse( $response ); };
|
||||
if ($@) {
|
||||
warn "could not deserialize response: $@";
|
||||
}
|
||||
else {
|
||||
return $PARSER->get_data();
|
||||
}
|
||||
if ($response->content) {
|
||||
eval { $PARSER->parse( $response->content() ); };
|
||||
return $PARSER->get_data() if (not $@);
|
||||
warn "could not deserialize response: $@";
|
||||
};
|
||||
|
||||
|
||||
require SOAP::WSDL::SOAP::Typelib::Fault11;
|
||||
# generate & return fault if we cannot serialize response
|
||||
# or have none...
|
||||
return SOAP::WSDL::SOAP::Typelib::Fault11->new({
|
||||
return $fault_class_of{$ident}->new({
|
||||
faultcode => 'soap:Server',
|
||||
faultactor => 'urn:localhost',
|
||||
faultstring => 'Error sending / receiving message: '
|
||||
. $soap->transport->message()
|
||||
. $response->message()
|
||||
#$soap->transport->message()
|
||||
});
|
||||
}
|
||||
eval { $PARSER->parse( $response ) };
|
||||
eval { $PARSER->parse( $response->content() ) };
|
||||
|
||||
# return fault if we cannot deserialize response
|
||||
if ($@) {
|
||||
return SOAP::WSDL::SOAP::Typelib::Fault11->new({
|
||||
return $fault_class_of{$ident}->new({
|
||||
faultcode => 'soap:Server',
|
||||
faultactor => 'urn:localhost',
|
||||
faultstring => "Error deserializing message: $@. \n"
|
||||
@@ -133,6 +153,52 @@ sub call {
|
||||
1;
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::Client - SOAP::WSDL's SOAP Client
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=head2 call
|
||||
|
||||
=head2 Configuration methods
|
||||
|
||||
=head3 outputxml
|
||||
|
||||
$soap->outputxml(1);
|
||||
|
||||
When set, call() returns the raw XML of the SOAP Envelope.
|
||||
|
||||
=head3 set_content_type
|
||||
|
||||
$soap->set_content_type('application/xml; charset: utf8');
|
||||
|
||||
Sets the content type and character encoding.
|
||||
|
||||
You probably should not use a character encoding different from utf8:
|
||||
SOAP::WSDL::Client will not convert the request into a different encoding
|
||||
(yet).
|
||||
|
||||
To leave out the encoding, just set the content type without appendet charset
|
||||
like in
|
||||
|
||||
text/xml
|
||||
|
||||
Default:
|
||||
|
||||
text/xml; charset: utf8
|
||||
|
||||
=head3 set_trace
|
||||
|
||||
$soap->set_trace(1);
|
||||
$soap->set_trace( sub { Log::Log4perl::get_logger()->debug( @_ ) } );
|
||||
|
||||
When set to a true value, tracing (via warn) is enabled.
|
||||
|
||||
When set to a code reference, this function will be called on every
|
||||
trace call, making it really easy for you to set up log4perl logging
|
||||
or whatever you need.
|
||||
|
||||
=head2 Features different from SOAP::Lite
|
||||
|
||||
@@ -145,7 +211,7 @@ Nonetheless SOAP::WSDL mimics part of SOAP::Lite's API and behaviour,
|
||||
so SOAP::Lite users can switch without looking up every method call in the
|
||||
documentation.
|
||||
|
||||
A few things are quite differentl from SOAP::Lite, though:
|
||||
A few things are quite different from SOAP::Lite, though:
|
||||
|
||||
=head3 SOAP request data
|
||||
|
||||
@@ -197,9 +263,28 @@ SOAP::WSDL::Client and implementing something like
|
||||
$soap_wsdl_client->call( mySoapMethod, @_);
|
||||
}
|
||||
|
||||
You may even do this in a class factory - SOAP::WSDL provides the methods
|
||||
for generating such interfaces.
|
||||
You may even do this in a class factory - see L<wsdl2perl.pl> for creating
|
||||
such interfaces.
|
||||
|
||||
=head3 Debugging / Tracing
|
||||
|
||||
While SOAP::Lite features a global tracing facility, SOAP::WSDL::Client
|
||||
allows to switch tracing on/of on a per-object base.
|
||||
|
||||
See L<set_trace|set_trace> on how to enable tracing.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
Copyright 2004-2007 Martin Kutter.
|
||||
|
||||
This file is part of SOAP-WSDL. You may distribute/modify it under
|
||||
the same terms as perl itself
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user