Suddenly receiving Premature end

C

custodian

I've been using a paypal ipn script for a few weeks and everything has
been fine, though I continually receive a "Premature end of script
headers" in my server logs. My concern of this was not immediate as the
script was still working as it should.

I'm now installing another shopping cart that relys on PHP and MySQL
which required me to install some additional items. In doing so I went
from Perl 5.8.6 to 5.8.7. Prior to this I was also using LWP which was
required by the script. I'm still getting the same error in the server
logs of "Premature end of script headers", but the output file used to
show the transaction (because it was working), now I receive
Transaction Error to the output file. I'm trying to determine if the
problem is with the perl code, or paypal. Can anyone see an error in
this that I am not seeing.

#!/usr/bin/perl
# program start
use CGI;
require "cartconfig.pl";

# read post from PayPal system and add 'cmd'
read (STDIN, $query, $ENV{'CONTENT_LENGTH'});
$query .= '&cmd=_notify-validate';

# post back to PayPal system to validate
use LWP::UserAgent;
$ua = new LWP::UserAgent;
$req = new HTTP::Request
'POST','http://www.paypal.com/cgi-bin/webscr/';
$req->content_type('application/x-www-form-urlencoded');
$req->content($query);
$res = $ua->request($req);

# split posted variables into pairs
@pairs = split(/&/, $query);
$count = 0;
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
$count++;
}

if ($res->is_error) {
$response="HTTP Error - Verify Payment Manually";
$paid="N";
}
if ($res->content eq 'VERIFIED' && uc($FORM{'receiver_email'}) eq
uc($PayPal_email)) {
$date=&get_date;
$response="PayPal Payment $FORM{'payment_status'} $date
Transaction ID: $FORM{'txn_id'}";
if ($FORM{'payment_status'} eq "Completed") {$paid="Y";} else
{$paid="N";}
}
else {
$response="PayPal Transaction Error";
$paid="N";
}


open(IN,"$order_file");
while(<IN>) {
chomp;
@field=split(/\|/,$_);
if ($field[0] eq $FORM{'item_number'}) {
$field[4]=$response;
}
$output.=join("|",@field);
$output.="\n";
}
close(IN);

open(OUT,">$order_file");

print OUT $output;

close(OUT);


#open (OUT,">ipn_test.txt");
#print OUT "$response\n\n";
#foreach $key (%FORM) {
# print OUT "$key: $FORM{$key}\n";
#}
#close(OUT);


The cartconfig.pl variables are mere email and return pages, which have
all been verified and working.


$ perl -c paypal_ipn.cgi
paypal_ipn.cgi syntax OK

Any suggestions? Is thi the perl code or do I need to look into apache
or paypal themselves?

Thanks!
Henry
 
D

Daniel Cutter

You'd get a lot further if you 'use strict' and 'use warnings'. You
should also catch all possible errors. Then you'd find out what's going
wrong. If Added bits here and there.
#!/usr/bin/perl
# program start
use strict;
use warnings;
use CGI;
require "cartconfig.pl";

# read post from PayPal system and add 'cmd'

read (STDIN, $query, $ENV{'CONTENT_LENGTH'}) or die "Error: Read
failed!\n$!\n";
$query .= '&cmd=_notify-validate';

# post back to PayPal system to validate
use LWP::UserAgent;
$ua = new LWP::UserAgent;
$req = new HTTP::Request 'POST','http://www.paypal.com/cgi-bin/webscr/';
$req->content_type('application/x-www-form-urlencoded');
$req->content($query);
$res = $ua->request($req);

# split posted variables into pairs
@pairs = split(/&/, $query);
$count = 0;
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
$count++;
}

if ($res->is_error) {
$response="HTTP Error - Verify Payment Manually";
$paid="N";
}
if ($res->content eq 'VERIFIED' && uc($FORM{'receiver_email'}) eq
uc($PayPal_email)) {
$date=&get_date;
$response="PayPal Payment $FORM{'payment_status'} $date
Transaction ID: $FORM{'txn_id'}";
if ($FORM{'payment_status'} eq "Completed") {$paid="Y";} else
{$paid="N";}
}
else {
$response="PayPal Transaction Error";
$paid="N";
}

open(IN,"$order_file") or die "Error opening '$order_file'!\n$!\n";
while(<IN>) {
chomp;
@field=split(/\|/,$_);
if ($field[0] eq $FORM{'item_number'}) {
$field[4]=$response;
}
$output.=join("|",@field);
$output.="\n";
}
close(IN);

open(OUT,">$order_file") or die "Error writing '$order_file'!\n$!\n";

print OUT $output;

close(OUT);


#open (OUT,">ipn_test.txt");
#print OUT "$response\n\n";
#foreach $key (%FORM) {
# print OUT "$key: $FORM{$key}\n";
#}
#close(OUT);


The cartconfig.pl variables are mere email and return pages, which have
all been verified and working.


$ perl -c paypal_ipn.cgi
paypal_ipn.cgi syntax OK

Any suggestions? Is thi the perl code or do I need to look into apache
or paypal themselves?

If you run the alterated code strict and warnings will tell what you did
wrong.

Daniel Cutter

print chr--$g+ord for'KWVX%GUW]RP^-^Tb]2[UXa\j#'=~m$.$g;
 
A

A. Sinan Unur

Can anyone see an error in this that I am not seeing.

Just the obvious stuff ...
#!/usr/bin/perl

use strict;
use warnings;

missing.

$CGI::pOST_MAX = 100*1024;
$CGI::DISABLE_UPLOADS = 1;
require "cartconfig.pl";

# read post from PayPal system and add 'cmd'
read (STDIN, $query, $ENV{'CONTENT_LENGTH'});

You are using CGI.pm, why not use it?

my $cgi = CGI->new;
$query .= '&cmd=_notify-validate';

$cgi->param(cmd => '_notify-validate');
# post back to PayPal system to validate
use LWP::UserAgent;
$ua = new LWP::UserAgent;
$req = new HTTP::Request
'POST','http://www.paypal.com/cgi-bin/webscr/';
$req->content_type('application/x-www-form-urlencoded');
$req->content($query);
$res = $ua->request($req);

# split posted variables into pairs

Again, use CGI.pm to parse the request. The stuff below is cut'n'paste,
cargo-cult programming.
@pairs = split(/&/, $query);
$count = 0;
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
$count++;

I also don't see why these lines are here.
if ($res->is_error) {
$response="HTTP Error - Verify Payment Manually";
$paid="N";
}
if ($res->content eq 'VERIFIED' && uc($FORM{'receiver_email'}) eq
uc($PayPal_email)) {
$date=&get_date;
$response="PayPal Payment $FORM{'payment_status'} $date
Transaction ID: $FORM{'txn_id'}";
if ($FORM{'payment_status'} eq "Completed") {$paid="Y";} else
{$paid="N";}
}

Please indent your code properly. I am having a very hard time figuring
out what you are doing here. Are you assuming that somehow posting the
contents of $query to the PayPal server is going to change the contents
of $query?

Where does $PayPal_email come from?

What the heck is &get_date?

Have you seen the posting guidelines for this group? Please read them.
They contain invaluable information you can use to help yourself, and
help others help you.
open(IN,"$order_file");

Always check if open succeeded.

Use lexical filehandles and the three argument form of open.

See also perldoc -q always
while(<IN>) {
chomp;
@field=split(/\|/,$_);
if ($field[0] eq $FORM{'item_number'}) {
$field[4]=$response;
}
$output.=join("|",@field);
$output.="\n";
}
close(IN);

open(OUT,">$order_file");

Always check if open succeeded.
print OUT $output;

This is a gaping security hole. You have not control over the amount of
data that will be written to $order_file if the open succeeds.

Sinan
 
S

Scott Bryce

custodian said:
I've been using a paypal ipn script for a few weeks and everything has
been fine, though I continually receive a "Premature end of script
headers" in my server logs. My concern of this was not immediate as the
script was still working as it should.

I'm now installing another shopping cart that relys on PHP and MySQL
which required me to install some additional items. In doing so I went
from Perl 5.8.6 to 5.8.7. Prior to this I was also using LWP which was
required by the script. I'm still getting the same error in the server
logs of "Premature end of script headers", but the output file used to
show the transaction (because it was working), now I receive
Transaction Error to the output file. I'm trying to determine if the
problem is with the perl code, or paypal. Can anyone see an error in
this that I am not seeing.

You have recieved some good advice on how to improve your script. As to
the two questions you asked, the answers are in the PayPal IPN
documentation. Since I don't have the IPN documentation in front of me,
and this is off topic in this group, I'll only give a couple of pointers.

1) When you post back to PayPal to validate the original post, make sure
you are correctly dealing with every possible response.

2) At some point you need to send a Status: 200 OK header back to PayPal.

PayPal has a forum where your questions can be answered by people who
understand the IPN system better than most of the regulars here.

http://paypal.forums.liveworld.com/index.jspa
 
T

Tad McClellan

Daniel Cutter said:


Who would?

Please provide an attribution when you quote someone.

open(IN,"$order_file") or die "Error opening '$order_file'!\n$!\n";
^^^^^^^^^^^^^

perldoc -q vars

What's wrong with always quoting "$vars"?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top