Hue-Bond has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to make a SOAP request from javascript using AJAX, thus getting my feet wet with two technologies and one programming language at the same time :^). I'm using a javascript SOAP client I've found here [guru4.net]. This client asks for the WSDL first, and does so by appending ?wsdl to the URL of the SOAP service.

So my simple SOAP service:

#!/usr/bin/perl use warnings; use strict; use lib '/home/hue/lang/perl/modules'; ## where Temperatures.pm lives use SOAP::Transport::HTTP; SOAP::Transport::HTTP::CGI->dispatch_to ('Temperatures')->handle;

Became:

#!/usr/bin/perl use warnings; use strict; use lib '/home/hue/lang/perl/modules'; use SOAP::Transport::HTTP; use CGI; my $q = CGI->new; my @keywords = $q->keywords; if (grep 'wsdl', @keywords) { print $q->header ('text/xml'); open my $fd, '<', 'temp.wsdl' or die "open: $!"; print while <$fd>; close $fd; exit; } SOAP::Transport::HTTP::CGI->dispatch_to ('Temperatures')->handle;

This code has a problem: CGI->new eats the input to the script and chokes on it. I remedied it by doing my $q = CGI->new ('') but this prevents me from accesing $q->keywords. So I had to resort to $ENV{'QUERY_STRING'}. The final code reads:

#!/usr/bin/perl use warnings; use strict; use lib '/home/hue/lang/perl/modules'; use SOAP::Transport::HTTP; use CGI; my $q = CGI->new (''); ## create empty query if ('wsdl' eq $ENV{'QUERY_STRING'}) { ## test for 'eq' is enough in t +his simple case print $q->header ('text/xml'); open my $fd, '<', 'temp.wsdl' or die "open: $!"; print while <$fd>; close $fd; exit; } SOAP::Transport::HTTP::CGI->dispatch_to ('Temperatures')->handle;

I realize that right now, CGI.pm is only used to send the proper header to the client. I think this is a good thing and see no point in removing CGI.pm from the equation, since probably Apache will have to load it for other scripts anyway. This runs under mod_perl, by the way.

Is this an acceptable way of doing it? Or is there a "better"TM method?

--
David Serrano

Replies are listed 'Best First'.
Re: SOAP server must offer WSDL document too
by izut (Chaplain) on Aug 07, 2006 at 08:45 UTC

    CGI.pm has a method called param keywords. It will define 'wsdl' if it is present return an array containing all keywords on QUERY_STRING. I suppose the following code will work:

    use CGI; use List::Util qw(first); my $q = CGI->new; if (first { $_ eq 'wsdl' } $q->keywords}) { ... }

    Update: changed from from $q->param $q->keywords on code.

    Igor 'izut' Sutton
    your code, your rules.

Re: SOAP server must offer WSDL document too
by cbrandtbuffalo (Deacon) on Feb 28, 2007 at 21:30 UTC
    I ran into the same problem and I don't see another way around the issue with CGI eating the input. The one difference is I found Pod::WSDL to generate my WSDL, so I have:
    my $pod = Pod::WSDL->new( source => 'My::Module', location => 'http://my/soap.cgi' pretty => 1, withDocumentation => 1, ); print CGI::header('text/xml'); print $pod->WSDL;
    in my wsdl block. Did you end up using the code in your post?