[Catalyst-commits] r7548 - in Catalyst-Controller-SOAP/1.0/trunk: . lib/Catalyst/Action/SOAP lib/Catalyst/Controller/SOAP t t/PostApp/lib/PostApp/Controller

ruoso at dev.catalyst.perl.org ruoso at dev.catalyst.perl.org
Wed Apr 2 15:54:42 BST 2008


Author: ruoso
Date: 2008-04-02 15:54:42 +0100 (Wed, 02 Apr 2008)
New Revision: 7548

Added:
   Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Action/SOAP/DocumentLiteralWrapped.pm
   Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Controller/SOAP/DocumentLiteralWrapped.pm
Modified:
   Catalyst-Controller-SOAP/1.0/trunk/MANIFEST
   Catalyst-Controller-SOAP/1.0/trunk/t/PostApp.t
   Catalyst-Controller-SOAP/1.0/trunk/t/PostApp/lib/PostApp/Controller/WithWSDL.pm
Log:
[C-C-SOAP] Document/Literal-Wrapped support (with a big ONLY FOR COMPATIBILTY REASONS disclaimer)... Test is still failing as the SOAPAction header seems to be lost in the test...

Modified: Catalyst-Controller-SOAP/1.0/trunk/MANIFEST
===================================================================
--- Catalyst-Controller-SOAP/1.0/trunk/MANIFEST	2008-04-02 11:25:02 UTC (rev 7547)
+++ Catalyst-Controller-SOAP/1.0/trunk/MANIFEST	2008-04-02 14:54:42 UTC (rev 7548)
@@ -23,8 +23,10 @@
 t/PostApp/postapp.yml
 lib/Catalyst/Action/SOAP.pm
 lib/Catalyst/Action/SOAP/DocumentLiteral.pm
+lib/Catalyst/Action/SOAP/DocumentLiteralWrapped.pm
 lib/Catalyst/Action/SOAP/HTTPGet.pm
 lib/Catalyst/Action/SOAP/RPCEndpoint.pm
 lib/Catalyst/Action/SOAP/RPCLiteral.pm
 lib/Catalyst/Controller/SOAP.pm
 lib/Catalyst/Controller/SOAP/RPC.pm
+lib/Catalyst/Controller/SOAP/DocumentLiteralWrapped.pm

Added: Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Action/SOAP/DocumentLiteralWrapped.pm
===================================================================
--- Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Action/SOAP/DocumentLiteralWrapped.pm	                        (rev 0)
+++ Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Action/SOAP/DocumentLiteralWrapped.pm	2008-04-02 14:54:42 UTC (rev 7548)
@@ -0,0 +1,110 @@
+{ package Catalyst::Action::SOAP::DocumentLiteralWrapped;
+  use strict;
+  use base qw(Catalyst::Action::SOAP);
+
+  sub execute {
+      my $self = shift;
+      my ( $controller, $c ) = @_;
+
+      $self->prepare_soap_helper(@_);
+
+      my $prefix = $controller->config->{soap_action_prefix};
+      my $soapaction = $c->req->headers->header('SOAPAction');
+
+      die 'No SOAP Action' unless $soapaction;
+
+      $soapaction =~ s/(^\"|\"$)//g;
+
+      die 'Bad SOAP Action: '.$soapaction unless
+        $prefix eq substr($soapaction,0,length($prefix));
+
+      my $operation = substr($soapaction,length($prefix));
+      my $action = $controller->action_for($operation);
+
+      die 'SOAP Action does not map to any operation' unless $action;
+
+      $c->dispatch($action);
+  }
+};
+
+1;
+
+__END__
+
+=head1 NAME
+
+Catalyst::Action::SOAP::DocumentLiteralWrapped - Document/Literal
+Wrapped SOAP ActionClass
+
+=head1 SYNOPSIS
+
+ # in the controller
+
+ __PACKAGE__->{config}{soap_action_prefix} = 'http://foo/bar/';
+
+ use base qw(Catalyst::Controller::SOAP::DocumentLiteralWrapped);
+ # or
+ sub endpoint : Local ActionClass(SOAP::DocumentLiteralWrapped) { }
+
+=head1 DESCRIPTION
+
+Microsoft has defined a pseudo-standard for SOAP usage called
+Document/Literal Wrapped. This standard is a deviation of both the
+Document/Literal and of the RPC/Literal usages.
+
+A Document/Literal service is supposed to have one operation per bind,
+as it's not techically possible to dispatch on the content of the
+Body. In fact, as the Body is used as "literal" the dispatching should
+not even look at it, it should be based on the port that received the
+request.
+
+RPC/Literal, on the other hand, supports the use of several operations
+per bind, and the dispatching of this operations is based on the first
+and only child element of the message body, which defines the
+operation. The arguments are set as the parts of the message in the
+WSDL.
+
+Document/Literal-Wrapped is a deviation of both, as the message should
+be interpreted as Document/Literal, but the dispatching requires an
+additional step of looking at the SOAPAction HTTP header, which will
+identify the proper operation to be dispatched.
+
+This is plain wrong, as the SOAP Action information should be used for
+routing pourposes only and not for operation dispatch. Please see the
+SOAP standard. In fact, SOAP1.2 even makes SOAPAction optional.
+
+=head1 WARNING
+
+THIS MODULE IS HERE FOR COMPATIBILITY REASONS ONLY, SO YOU CAN USE
+WHEN IN NEED TO IMPLEMENT A LEGACY SERVICE THAT USES THIS
+PSEUDO-STANDARD. THIS USAGE SCENARIO SHOULD NOT BE PROMOTED BY ANY
+WAY. THE CORRECT WAY TO IMPLEMENT THE SAME FUNCTIONALITY IS BY USING
+RPC/Literal, THAT WILL IN PRODUCE THE EXACT SAME MESSAGE BODY.
+
+=head1 USE
+
+The operation is dispatched according to the SOAPAction header. The
+operation name is extracted by removing the given prefix and assuming
+the rest of the SOAPAction is the effective operation name (removing
+"s).
+
+=head1 TODO
+
+Well, here? nothing, all the work is done in the superclass.
+
+=head1 AUTHOR
+
+Daniel Ruoso <daniel.ruoso at verticalone.pt>
+
+=head1 BUG REPORTS
+
+Please submit all bugs regarding C<Catalyst::Controller::SOAP> to
+C<bug-catalyst-controller-soap at rt.cpan.org>
+
+=head1 LICENSE
+
+This library is free software, you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+

Added: Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Controller/SOAP/DocumentLiteralWrapped.pm
===================================================================
--- Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Controller/SOAP/DocumentLiteralWrapped.pm	                        (rev 0)
+++ Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Controller/SOAP/DocumentLiteralWrapped.pm	2008-04-02 14:54:42 UTC (rev 7548)
@@ -0,0 +1,81 @@
+{ package Catalyst::Controller::SOAP::DocumentLiteralWrapped;
+  use strict;
+  use base qw(Catalyst::Controller::SOAP);
+  sub rpc_endpoint :Path('') :ActionClass('SOAP::DocumentLiteralWrapped') { };
+};
+
+1;
+
+__END__
+
+=head1 NAME
+
+Catalyst::Controller::SOAP::DocumentLiteralWrapped - Helper controller for SOAP
+
+=head1 SYNOPSIS
+
+ use base qw(Catalyst::Controller::SOAP::DocumentLiteralWrapped);
+ __PACKAGE__->{config}{soap_action_prefix} = 'http://foo/bar/';
+
+=head1 DESCRIPTION
+
+Microsoft has defined a pseudo-standard for SOAP usage called
+Document/Literal Wrapped. This standard is a deviation of both the
+Document/Literal and of the RPC/Literal usages.
+
+A Document/Literal service is supposed to have one operation per bind,
+as it's not techically possible to dispatch on the content of the
+Body. In fact, as the Body is used as "literal" the dispatching should
+not even look at it, it should be based on the port that received the
+request.
+
+RPC/Literal, on the other hand, supports the use of several operations
+per bind, and the dispatching of this operations is based on the first
+and only child element of the message body, which defines the
+operation. The arguments are set as the parts of the message in the
+WSDL.
+
+Document/Literal-Wrapped is a deviation of both, as the message should
+be interpreted as Document/Literal, but the dispatching requires an
+additional step of looking at the SOAPAction HTTP header, which will
+identify the proper operation to be dispatched.
+
+This is plain wrong, as the SOAP Action information should be used for
+routing pourposes only and not for operation dispatch. Please see the
+SOAP standard. In fact, SOAP1.2 even makes SOAPAction optional.
+
+=head1 WARNING
+
+THIS MODULE IS HERE FOR COMPATIBILITY REASONS ONLY, SO YOU CAN USE
+WHEN IN NEED TO IMPLEMENT A LEGACY SERVICE THAT USES THIS
+PSEUDO-STANDARD. THIS USAGE SCENARIO SHOULD NOT BE PROMOTED BY ANY
+WAY. THE CORRECT WAY TO IMPLEMENT THE SAME FUNCTIONALITY IS BY USING
+RPC/Literal, THAT WILL PRODUCE THE EXACT SAME MESSAGE BODY.
+
+=head1 USE
+
+The operation is dispatched according to the SOAPAction header. The
+operation name is extracted by removing the given prefix and assuming
+the rest of the SOAPAction is the effective operation name (removing
+"s).
+
+=head1 TODO
+
+Well, here? nothing, all the work is done in the superclass.
+
+=head1 AUTHOR
+
+Daniel Ruoso <daniel.ruoso at verticalone.pt>
+
+=head1 BUG REPORTS
+
+Please submit all bugs regarding C<Catalyst::Controller::SOAP> to
+C<bug-catalyst-controller-soap at rt.cpan.org>
+
+=head1 LICENSE
+
+This library is free software, you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+

Modified: Catalyst-Controller-SOAP/1.0/trunk/t/PostApp/lib/PostApp/Controller/WithWSDL.pm
===================================================================
--- Catalyst-Controller-SOAP/1.0/trunk/t/PostApp/lib/PostApp/Controller/WithWSDL.pm	2008-04-02 11:25:02 UTC (rev 7547)
+++ Catalyst-Controller-SOAP/1.0/trunk/t/PostApp/lib/PostApp/Controller/WithWSDL.pm	2008-04-02 14:54:42 UTC (rev 7548)
@@ -5,6 +5,7 @@
 use base 'Catalyst::Controller::SOAP';
 
 __PACKAGE__->config->{wsdl} = 't/hello.wsdl';
+__PACKAGE__->config->{soap_action_prefix} = 'http://example.com/actions/';
 
 sub Greet : Local SOAP('DocumentLiteral') {
     my ( $self, $c, $args ) = @_;
@@ -13,4 +14,6 @@
     $c->stash->{soap}->compile_return({ details => { greeting => $grt.' '.$who.'!' }});
 }
 
+sub doclw : Local ActionClass('SOAP::DocumentLiteralWrapped') { }
+
 1;

Modified: Catalyst-Controller-SOAP/1.0/trunk/t/PostApp.t
===================================================================
--- Catalyst-Controller-SOAP/1.0/trunk/t/PostApp.t	2008-04-02 11:25:02 UTC (rev 7547)
+++ Catalyst-Controller-SOAP/1.0/trunk/t/PostApp.t	2008-04-02 14:54:42 UTC (rev 7548)
@@ -1,4 +1,4 @@
-use Test::More tests => 8;
+use Test::More tests => 9;
 use File::Spec::Functions;
 use HTTP::Response;
 use IPC::Open3;
@@ -32,6 +32,12 @@
 ok($response->content =~ /greeting\>Hello World\!\<\//, 'Literal response: '.$response->content);
 
 $response = soap_xml_post
+  ('/withwsdl/doclw',
+   '<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"><Body><GreetingSpecifier><who>World</who><greeting>Hello</greeting></GreetingSpecifier></Body></Envelope>'
+  );
+ok($response->content =~ /greeting\>Hello World\!\<\//, ' Document/Literal Wrapped response: '.$response->content);
+
+$response = soap_xml_post
   ('/withwsdl2/Greet','
     <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
          <Body>
@@ -48,15 +54,16 @@
   ('/withwsdl2/Greet','
     <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
          <Body>
-               <GreetingSpecifier>
-                   <who><Big>W</Big><Small>orld</Small></who>
-                   <greeting>Hello</greeting>
-               </GreetingSpecifier>
+            <Greet>
+               <who>World</who>
+               <greeting>Hello</greeting>
+            </Greet>
          </Body>
     </Envelope>
   ');
-ok($response->content =~ /Fault/, 'Fault on malformed body for RPC-Literal: '.$response->content);
+ok($response->content =~ /greeting[^>]+\>Hello World\!\<\//, 'Literal response: '.$response->content);
 
+
 $response = soap_xml_post
   ('/withwsdl/Greet',
    '<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"><Body><GreetingSpecifier><name>World</name><greeting>Hello</greeting></GreetingSpecifier></Body></Envelope>'
@@ -85,6 +92,7 @@
     $ENV{REQUEST_METHOD} ='POST';
     $ENV{SERVER_PORT} ='80';
     $ENV{SERVER_NAME} ='pitombeira';
+    $ENV{SOAPAction} = 'http://example.com/actions/Greet';    
 
     my ($writer, $reader, $error) = map { gensym() } 1..3;
     my $pid = open3($writer, $reader, $error,




More information about the Catalyst-commits mailing list