http://qs321.pair.com?node_id=1022106

htmanning has asked for the wisdom of the Perl Monks concerning the following question:

Monks, I've been using this script with Paypal's instant payment notification and it has worked perfectly. Today Paypal stopped receiving 200 responses from us, and they say it's because this script is sending http 1.0 headers and we need to send http 1.1 headers instead. How do I do that? If paypal calls this script, it replies with a 1.0 response. If I call the script from a browser the logs indicate a version 1.1 response is sent. I'm lost. UPDATE: It looks like all POSTS to the script return http 1.0 responses and all GETS return a http 1.0 response.
#!/usr/bin/perl use LWP::UserAgent; print "Content-type: text/plain\n\n"; # 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 $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 1 }); # when testing change sandbox url here $req = HTTP::Request->new('POST', 'https://www.paypal.com/cgi-bin/webs +cr'); $req->content_type('application/x-www-form-urlencoded'); # and here $req->header(Host => 'www.paypal.com'); $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; $variable{$name} = $value; $count++; } # assign posted variables to local variables $item_name = $variable{'item_name'}; $item_number = $variable{'item_number'}; $payment_status = $variable{'payment_status'}; $payment_amount = $variable{'mc_gross'}; $payment_currency = $variable{'mc_currency'}; $txn_id = $variable{'txn_id'}; $receiver_email = $variable{'receiver_email'}; $payer_email = $variable{'payer_email'}; $custom = $variable{'custom'}; if ($res->is_error) { # HTTP error # do whatever necessary print "ERROR: http_error! (Not sure what this is)\n"; $ipnerror = "http_error"; &error1; } elsif ($res->content eq 'VERIFIED') { print "PayPal responded VERIFIED.\n"; # check the $payment_status=Completed if ($payment_status ne "Completed") { # do whatever necessary print "Payment status was not Completed.\n"; $ipnerror = "Payment status was not completed."; &error1; } # check that $receiver_email is your Primary PayPal email elsif ($receiver_email ne "info\@email.com") { # do whatever necessary print "Receiver email was incorrect.\n"; $ipnerror = "Receiver email was incorrect"; &error1; } # process payment else { # everything ok, update your database # split 4 passthrough variables in "custom", separated by comma (',' +) # change separator char if necessary print "Everything should be ok.\n"; my ($user1, $user2, $user3) = split(/,/, $custom, 3); my $response = $ua->post('http://www.mydomain.com/cgi-bin/add-listin +g.pl', { 'USER1' => $user1, 'USER2' => $user2, 'USER3' => $user3, 'RESULT' => '0' } ); unless ($response->is_success) { print "Posting to add-listing.pl failed.\n"; $ipnerror = "Posting to add-listing.pl failed."; &error1; # request failed } # parse server response my $resdec = $response->decoded_content; } } elsif ($res->content eq 'INVALID') { # log for manual investigation # do whatever necessary print "PayPal responded INVALID. (Probably means it didn't get called + from Paypal.)\n"; $ipnerror = "PayPal responded INVALID. (Probably means it didn't +get called from Paypal.)"; &error1; } else { # error # do whatever necessary print "Unexpected response from PayPal.\n"; $ipnerror = "Unexpected response from PayPal."; &error1; } sub error1 { $notify_admin2 = "1"; #1=yes, 0=no $mailprog = "/usr/sbin/sendmail"; if ($notify_admin2 eq "1") { # send mail with activate link to admin open (MAIL, "|$mailprog info\@email.com") || die "Can't open $ +mailprog!\n"; print MAIL "From: $sitename <admin\@email.com>\n"; print MAIL "Reply-to: $sitename <admin\@email.com>\n"; print MAIL "To: info@email.com\n"; print MAIL "Subject: IPN Handler Error\n"; print MAIL "Content-type: text/plain\n"; print MAIL "There was an IPN Handler error.\n\n"; print MAIL "Error: $ipnerror\n\n"; print MAIL "User1: $user1\n"; print MAIL "User2: $user2\n"; print MAIL "User3: $user3\n"; print MAIL "This email sent by ipn-handler.pl. \n\n"; close (MAIL); } } #end sub print "Done\n";

Replies are listed 'Best First'.
Re: Need help with http 1.1 headers
by Athanasius (Archbishop) on Mar 07, 2013 at 03:30 UTC

    A side note: The script doesn’t use strict. When I added this, it uncovered two errors in sub error1:

    1. The variable $sitename is not defined.

    2. In the line:

      print MAIL "To: info@email.com\n";

      the @ symbol is not escaped, meaning the (non-existent) array @email will be interpolated, producing: To: info.com.

    Moral: Always use strict !

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: Need help with http 1.1 headers
by Khen1950fx (Canon) on Mar 07, 2013 at 03:11 UTC
    Use keep_alive => 1 in the constructor. It'll setup a conncache and enable HTTP/1.1.
    #/usr/bin/perl use strict; use warnings; use LWP::Useragent; my $ua = LWP::UserAgent->new( keep_alive => 1, ssl_opts => { verify_hostname => 1 }, );
Re: Need help with http 1.1 headers (use CGI)
by Anonymous Monk on Mar 07, 2013 at 10:13 UTC

    # split posted variables into pairs

    If you're gonna do that, why not drop LWP entirely and just use IO::Socket?

    At the very least you should use CGI.pm for params, see Re^3: Get those parameters without CGI.pm as to why

    Basically, whatever the problem with your program, chances are its because you're not using CGI.pm -- it probably has nothing to do with http 1.1 at all

    yet another argument for using some paypal module

Re: Need help with http 1.1 headers
by Anonymous Monk on Mar 07, 2013 at 10:01 UTC

    and they say it's because this script is sending http 1.0 headers and we need to send http 1.1 headers instead.

    IIRC, every http 1.1 server should speak http 1.0 without any problems, so paypal is lame:)

    Also, I would use some paypal module instead of reinventing it :) but thats just me