• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 808
  • Last Modified:

perl with soap-lite runs on windows but not debian

I have downloaded the program below from the book "Amazon Hacks"

Runs fine on windows.
Trying it on debian. Using apt-get for required modules since debian didn't work with cpan.

Found all the necessary packages (assumption since I eliminated all the compiled errors)

instmodsh doeesn't seem to identify the debian packages as installed perl modules.

program runs but no output and id probably not connecting to Amazon Web Services.

yes, I edited to add my dev token and my tag

any suggestions on how to debug or see if it is connecting?



#!/usr/bin/perl
# amazon.pl
# A typical Amazon Web API Perl script that uses the SOAP::Lite Module.
# Usage: perl amazon.pl <keyword>

#Your Amazon developer's token
my $dev_token='insert developer token';

#Your Amazon affiliate code
my $af_tag='insert associate tag';

#Location of the Amazon WSDL file
my $amazon_wdsl = "http://soap.amazon.com/schemas2/AmazonWebServices.wsdl";

use strict;

#Use the SOAP::Lite Perl module
use SOAP::Lite;

#Take the query from the command-line
my $keyword =shift @ARGV or die "Usage:perl amazon.pl <keyword>\n";

#Create a new SOAP::Lite instance, feeding it Amazon's WSDL
my $amazon_search = SOAP::Lite->service("$amazon_wdsl");

#Query Amazon
my $results = $amazon_search ->
    KeywordSearchRequest(SOAP::Data->name("KeywordSearchRequest")
        ->type("KeywordRequest")
           ->value(\SOAP::Data->value(
        SOAP::Data->name("keyword" => $keyword),
        SOAP::Data->name("page" => "1"),
        SOAP::Data->name("mode" => "books"),
        SOAP::Data->name("tag" => $af_tag),
        SOAP::Data->name("type" => "lite"),
        SOAP::Data->name("devtag" => $dev_token)
        ))
    );

foreach my $result (@{$results->{Details}}){
    #Print out the main bits of each result
    print
        $result->{ProductName}|| "no title",
        "\nby ",
        join (', ', @{$result->{Authors}}),
        "\n$result->{OurPrice}",
        "\nASIN: $result->{Asin}",
        "\n\n";
}
0
aijohn
Asked:
aijohn
  • 6
  • 4
1 Solution
 
clockwatcherCommented:
Not sure why you had problems with CPAN and your debian install.  Regardless, SOAP::Lite has tracing support.  To use it, comment out the use strict and add a +trace to your use SOAP::Lite line.  It'll spit out details of what is going on.

...
#Location of the Amazon WSDL file
my $amazon_wdsl = "http://soap.amazon.com/schemas2/AmazonWebServices.wsdl";

# use strict;

#Use the SOAP::Lite Perl module
use SOAP::Lite +trace;
...
0
 
clockwatcherCommented:
Not really thinking today... you can keep the strict in place with:

use SOAP::Lite +'trace';
0
 
aijohnAuthor Commented:
Thanks,

Now, how do I get all that beautiful spit out into a text file so I can look at it?
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
clockwatcherCommented:
It spits it to stderr:

   perl amazon.pl keyword 2> traceoutput.txt
0
 
aijohnAuthor Commented:
Got it!  Thanks.

Going to be away from the computer for a few hours but wil compare it to a trace from windows and see if I can learn anything.

Amazon said in STDERR
"The request contains an invalid SOAP body."
0
 
aijohnAuthor Commented:
Below is part of the trace from linux debian

It appears that none of the request after

ypens:KeywordRequest" /></typens:KeywordSearchRequest>

is being sent in the request

I can see all of the data in the windows trace but none in the linux request


SOAP::Transport::HTTP::Client::send_receive: HTTP::Request=HASH(0x86a4fec)
SOAP::Transport::HTTP::Client::send_receive: POST http://soap.amazon.com/onca/soap2 HTTP/1.1
Accept: text/xml
Accept: multipart/*
Accept: application/soap
Content-Length: 582
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://soap.amazon.com"

<?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:typens="http://soap.amazon.com" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><typens:KeywordSearchRequest><KeywordSearchRequest xsi:nil="true" xsi:type="typens:KeywordRequest" /></typens:KeywordSearchRequest></soap:Body></soap:Envelope>
SOAP::Transport::HTTP::Client::send_receive: HTTP::Response=HASH(0x871557c)
SOAP::Transport::HTTP::Client::send_receive: HTTP/1.1 200 OK
0
 
aijohnAuthor Commented:
more detail of comppare


windows

Accept: text/xml
Accept: multipart/*
Content-Length: 885
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://soap.amazon.com"

<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:namesp2="http://namespaces.soaplite.com/perl" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><namesp1:KeywordSearchRequest xmlns:namesp1="http://soap.amazon.com"><KeywordSearchRequest xsi:type="namesp2:KeywordRequest"><keyword xsi:type="xsd:string">boogie</keyword><page xsi:type="xsd:int">1</page><mode xsi:type="xsd:string">books</mode><tag xsi:type="xsd:string">xxxxxx</tag><type xsi:type="xsd:string">lite</type><devtag xsi:type="xsd:string">xxxxxxxxx</devtag></KeywordSearchRequest></namesp1:KeywordSearchRequest></SOAP-ENV:Body></SOAP-ENV:Envelope>
SOAP::Transport::HTTP::Client::send_receive: HTTP::Response=HASH(0x1f80384)
SOAP::Transport::HTTP::Client::send_receive: HTTP/1.1 200 OK
Connection: close

linux

Accept: text/xml
Accept: multipart/*
Accept: application/soap
Content-Length: 582
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://soap.amazon.com"

<?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:typens="http://soap.amazon.com" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><typens:KeywordSearchRequest><KeywordSearchRequest xsi:nil="true" xsi:type="typens:KeywordRequest" /></typens:KeywordSearchRequest></soap:Body></soap:Envelope>
SOAP::Transport::HTTP::Client::send_receive: HTTP::Response=HASH(0x871557c)
SOAP::Transport::HTTP::Client::send_receive: HTTP/1.1 200 OK
Connection: close
0
 
clockwatcherCommented:
You're using two different versions of SOAP::Lite.  The SOAP::Lite that ActiveState installs and distributes is the original Kulchenko version 0.55.  The current version on CPAN is 0.69 and is being maintained by a new author.  The new version appears to break things (probably for progress reasons-- not a SOAP::Lite user so couldn't tell you)-- but I'd guess the breakage would be why ActiveState distributes the old one.  Anyway... that explains why you're seeing different results.

I looked at it a bit and the service method call is generating a stub with a messed up (essentially empty) parameter list. template  The KeywordSearchRequest method is called and it goes to the templated parameter list to put together the parameters it uses to make the actual SOAP body-- and since the template is empty the body is generated without any parameters (no matter what you pass it).

The easiest way to "fix" it is to uncomment line 3004 (assuming version 0.69) in Lite.pm.  Change:

    foreach (@{$services->{$service}{parameters}}) {
    #  next unless $_;
      $self->{'_stub'} .= "      SOAP::Data->new(name => '".$_->name."', type =>

To:

    foreach (@{$services->{$service}{parameters}}) {
      next unless $_;
      $self->{'_stub'} .= "      SOAP::Data->new(name => '".$_->name."', type =>

I can't tell you why the author commented that line out, but with it commented out the thing generates empty parameter lists (with Amazon's WSDL anyway) and with that empty parameter list template it won't create a soap body with parameters.  With the right magic words, the current SOAP::Lite might generate a correct templated parameter list.  I just don't have any idea what the code would be to get it to do that.

If you don't want to modify Lite.pm, then I'd suggest not using the service method to generate stubs from Amazon's WSDL and just calling the method straight out:

#!/usr/bin/perl
use strict;
use SOAP::Lite;

#Your Amazon developer's token
my $dev_token='YOURTOKEN';

#Your Amazon affiliate code
my $af_tag='YOURTOKEN';

#Take the query from the command-line
my $keyword =shift @ARGV or die "Usage:perl amazon.pl <keyword>\n";

my $results = SOAP::Lite->proxy('http://soap.amazon.com/onca/soap2')->uri('http://soap.amazon.com')->KeywordSearchRequest( {keyword=>$keyword, page=>1, mode=>'books', tag=>$af_tag, type=> 'lite', devtag=>$af_tag } )->result;

foreach my $result (@{$results->{Details}}){
    #Print out the main bits of each result
    print
        $result->{ProductName}|| "no title",
        "\nby ",
        join (', ', @{$result->{Authors}}),
        "\n$result->{OurPrice}",
        "\nASIN: $result->{Asin}",
        "\n\n";
}

If you really want to use the service method and WSDL, maybe someone will know the right magic words.  Personally, I'd just uncomment the line until I ran across a WSDL that broke it.  I can't imagine why having that line in there would be a problem.  It really seems like it should be in there.  The only thing commenting out that line seems like it could possibly do is break things.  But the author must have commented it out for some reason and I'm pretty sure it wasn't to break things.
0
 
aijohnAuthor Commented:
Thanks, it worked with one small change.  If anyone checks out this excellent answer, change the second $af_tag to $dev_key.

my $results = SOAP::Lite->proxy('http://soap.amazon.com/onca/soap2')->uri('http://soap.amazon.com')->KeywordSearchRequest( {keyword=>$keyword, page=>1, mode=>'books', tag=>$af_tag, type=> 'lite', devtag=>$af_tag } )->result;

should be

my $results = SOAP::Lite->proxy('http://soap.amazon.com/onca/soap2')->uri('http://soap.amazon.com')->KeywordSearchRequest( {keyword=>$keyword, page=>1, mode=>'books', tag=>$af_tag, type=> 'lite', devtag=>$dev_key } )->result;

0
 
aijohnAuthor Commented:
Yes, modifying Lite.pm  also worked.  No longer thinking evil thoughts about debian packages.

Thanks again for the solutions.
0

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

  • 6
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now