Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Convert SOAP service from CGI to Mod-Perl (ModPerl::Registry)

by banco (Initiate)
on Oct 01, 2010 at 17:55 UTC ( #862997=perlquestion: print w/ replies, xml ) Need Help??
banco has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks

I looked around the monestary for an existing thread that may address this issue and found some similar by not precisely what I need.

My environment looks like this ...

HTTP_ACCEPT_ENCODING gzip,deflate
HTTP_CONNECTION keep-alive
REQUEST_METHOD GET
HTTP_ACCEPT text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
SERVER_SOFTWARE Apache/2.2.3 (Red Hat)
HTTP_ACCEPT_CHARSET ISO-8859-1,utf-8;q=0.7,*;q=0.7
QUERY_STRING
SERVER_PORT 80
SERVER_SIGNATURE <address>Apache/2.2.3 (Red Hat) Server at my.server.com Port 80</address>
HTTP_ACCEPT_LANGUAGE en-us,en;q=0.5
HTTP_KEEP_ALIVE 300
SERVER_PROTOCOL HTTP/1.1
MOD_PERL_API_VERSION 2
GATEWAY_INTERFACE CGI/1.1
DOCUMENT_ROOT /var/www/html
HTTP_HOST my.server.com
MOD_PERL mod_perl/2.0.4

The issue -- I have a functional CGI-based, Perl SOAP service running on RHEL-5 using Perl 5.8.8 and SOAP::Lite 7.12. I need to convert this service from CGI to MOD-Perl using ModPerl::Registry.

I installed mod perl, created a new directory at /var/www/perl and placed a copy of my CGI dispatcher script (hello.cgi) in that directory and made the corresponding change in my client to point the proxy to the new file/directory. I also added the following directive to the httpd.conf file ...

Alias /perl/ /var/www/perl/ <Location /perl> SetHandler perl-script PerlResponseHandler ModPerl::Registry Options +ExecCGI Order allow,deny Allow from all </Location>

Here is my client (hello.pl)

#!/usr/bin/perl use strict; local $SIG{__WARN__}=sub{}; use lib '/home/my_user/lib'; use Getopt::Long; my $DEBUG; my $result = GetOptions ("d" => \$DEBUG); if ($DEBUG) { eval "use SOAP::Lite +trace => 'debug';"; } else { eval "use SOAP::Lite;"; } print SOAP::Lite -> uri("urn:Hello") -> proxy('http://my.domain.com/perl/hello.cgi') # mod_perl # -> proxy('http://my.domain.com/cgi-bin/hello.cgi') # mod_cgi -> hello() -> result . "\n";

Here is my handler (Hello.pm)

package Hello; sub hello { return "hello, world"; } 1;

Here is my dispatcher (hello.cgi)

#!/usr/bin/perl use lib '/home/my_user/lib'; use SOAP::Transport::HTTP; SOAP::Transport::HTTP::CGI -> dispatch_to('Hello') -> handle;

The CGI-based version of hello.pl behaves as expected and returns the "hello world" string. Here is the Trace-Debug replay ...

SOAP::Transport::HTTP::Client::send_receive: HTTP/1.1 200 OK<br> Connection: close<br> Date: Thu, 30 Sep 2010 22:43:02 GMT<br> Server: Apache/2.2.3 (Red Hat)<br> <b>Content-Length: 473</b><br> <b>Content-Type: text/xml; charset=utf-8<br></b> Client-Date: Thu, 30 Sep 2010 22:43:02 GMT<br> Client-Peer: 192.168.32.50:80<br> Client-Response-Num: 1<br> SOAPServer: SOAP::Litebrerl/0.712 <?xml version="1.0" encoding="UTF-8"?><br> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<b +r> xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"<br> xmlns:xsd="http://www.w3.org/2001/XMLSchema"<br> soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" <br> xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><br> <soap:Body><helloResponse xmlns="urn:Hello"><br> <s-gensym3 xsi:type="xsd:string">hello, world</s-gensym3><br> </helloResponse></soap:Body></soap:Envelope><br> <b>hello, world</b>

The Mod-Perl version of hello.pl does not return the "hello world" string and indeed issues a '500 Internal Server Error' -- here is the Trace-Debug replay

SOAP::Transport::HTTP::Client::send_receive: HTTP/1.1 200 OK
Connection: close
Date: Fri, 01 Oct 2010 15:00:07 GMT
Server: Apache/2.2.3 (Red Hat)
Content-Type: text/plain; charset=UTF-8
Client-Date: Fri, 01 Oct 2010 15:00:07 GMT
Client-Peer: 192.168.32.50:80
Client-Response-Num: 1
Client-Transfer-Encoding: chunked

Status: 500 Internal Server Error
Content-Length: 521
Content-Type: text/xml; charset=utf-8
SOAPServer: SOAP::Litebrerl/0.712

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body><soap:Fault><faultcode>soap:Client</faultcode>
<faultstring>Application failed during request deserialization: no element found
</faultstring></soap:Fault></soap:Body></soap:Envelope>

There are several differences between the debug of the CGI-based and Mod-Perl versions of hello.pl

CGI issues a Content-Length and a Content-Type of text/xml whereas Mod-Perl does not issue a Content-Length (thus Chunking) and issues a Content-Type of text/plain

Then the 500 error is issued resulting in a SOAP fault of "Application failed during request deserialization: no element found"

I suspect the differences I see in the debug(s) hold the answer to why my Mod-Perl version is not working. I would greatly appreciate someone having experience with SOAP/Mod-Perl/Apache looking this over and pointing me in a direction toward repairing my service.

If more information is needed -- I will gladly post it.

Thank You and please excuse the bandwidth

Comment on Convert SOAP service from CGI to Mod-Perl (ModPerl::Registry)
Select or Download Code
Re: Convert SOAP service from CGI to Mod-Perl (ModPerl::Registry)
by halfcountplus (Hermit) on Oct 01, 2010 at 18:21 UTC

    I have not used Modperl::Registry or SOAP::Transport, so the purpose of the "Hello.pm" handler is not clear to me BUT I have written perl modules for use under mod perl and if this handler module is used the same way by Modperl::Registry:

    package Hello; sub hello { return "hello, world"; } 1;

    Then the function "hello" should be called "handler" -- that is the function mod_perl uses at instantiation of the package, much like a function "new" is required to instantiate an object. Are you sure this is not the case here? Just a thought.

Re: Convert SOAP service from CGI to Mod-Perl (ModPerl::Registry)
by Anonymous Monk on Oct 02, 2010 at 00:01 UTC

      That is one of the links I'm using for my examples/guides. I will go over it again to see what I may have mis-interpreted or just plain missed. Thanks for the reply.

Re: Convert SOAP service from CGI to Mod-Perl (ModPerl::Registry)
by jakeease (Friar) on Oct 02, 2010 at 02:03 UTC

    handlers are commonly named "handler" but it's not required. Do you have a PerlModule directive in httpd.conf?

    PerlModule Hello
      >>handlers are commonly named "handler" but it's not required.

      Just to clarify -- I did not say the handler had to be called "handler". What I said was the handler must contain a primary function, handler(), the same way an object definition must contain a function, new(), in order to be instantantiated as such. This IS REQUIRED by Apache, and hence mod perl. If you DO NOT have such a function, you will get the following apache error, eg:

      failed to resolve handler Hello

      I was just guessing that the OP was looking at an example "package handler" that had the primary function, handler(), and decided to rename not just the package -- which can be called anything, but that will be the name you use to register it -- and the handler() function, which would be a mistake, because it MUST be called handler() for the module to work.

        >>the OP ... decided to rename not just the package -- which can be called >>anything, ... and the handler() function, which would be a mistake, because it >>MUST be called handler() for the module to work.

        I agree that he should have named it handler() for it to work with the configuration and suggested changes to it. But it is NOT required to name the handler routine "handler()". It can be called anything. To make the OP's handler work, something like the following directive would be needed:

        PerlHandler Hello::hello #or PerlHandler Hello->hello

        Since I didn't point that out, that part of my response was more of a distraction than solution, and yours a significant step toward a solution.

      I wasn't aware of that particular directive. I'll check it out ... thanks for the reply.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://862997]
Approved by ikegami
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (6)
As of 2014-12-20 01:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (95 votes), past polls