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

How do POST to another Webpage with CGI

Hello, I am trying to create a PayPal situation where I do not use the standard form but instead have all of the info within a CGI script to be POSTed to the PayPal secure server when the script is accessed.

I am working with what I have learned from www.perldoc.com about the subject but keep getting a 500 Internal Server error.

This is what I have:
---------------------------------------------------------------------------------

#!/usr/bin/perl -w

use LWP::UserAgent;
$ua = LWP::UserAgent->new;

my $req = HTTP::Request->new(POST => 'https://www.paypal.com/cgi-bin/webscr');
$req->content_type('application/x-www-form-urlencoded');
$req->content('cmd=_xclick&business=ziffgone@telus.net&item_name=MASSIVE Webmaster's Resale Package&item_number=MWRP001&amount=69.95&return=http://webmastereseller.com/********&cancel_return=http://webmastereseller.com&no_note=1¤cy_code=USD');

my $res = $ua->request($req);
print $res->as_string;
---------------------------------------------------------------------------------

I have tried escaping all special characters only to get the same result. Any idea why this isn't sending the content to PayPal? Should I be using a different Perl header than "-w"?

Thanks...
0
ziffgone
Asked:
ziffgone
  • 8
  • 7
1 Solution
 
MercantilumCommented:
What did you get in your /var/log/httpd/error_log (or equivalent) when the error occured?
0
 
ziffgoneAuthor Commented:
Hi Mercantilum,

This is what I got:
Premature end of script headers: /home/pwolf/public_html/cgi-bin/test_post.cgi

Thanks...
0
 
MercantilumCommented:
This is typically when the famous line
    print "Content-type: text/html\n\n"; # or image or ...
is missing in the CGI script ...

Have a look to http://perlmonks.thepen.com/24447.html too.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
ziffgoneAuthor Commented:
I had the script print Fatals out to browser now and ends up I had a sintax error.
Fixed this but I also received the following error and don't know how to fix:

This is what I got:

Global symbol "$ua" requires explicit package name at test_post.cgi line 9

Line 9 = "$ua = LWP::UserAgent->new;"

Global symbol "$ua" requires explicit package name at test_post.cgi line 15

Line 15 = "my $res = $ua->request($req);"

What's the explicit package I need to be assigning?

CURRENT SCRIPT:
-----------------------------------------------------------------------------------
#!/usr/bin/perl -w

use strict;
use CGI;

use LWP::UserAgent;
$ua = LWP::UserAgent->new;

my $req = HTTP::Request->new(POST => 'https://www.paypal.com/cgi-bin/webscr');
$req->content_type('application/x-www-form-urlencoded');
$req->content('cmd=_xclick&business=ziffgone\@telus\.net&item_name=MASSIVE Webmaster\&\#39\;s Resale Package&item_number=MWRP001ref=booj\@boogiejack\.com&amount=69\.95&return=http://webmastereseller\.com/*********&cancel_return=http://webmastereseller\.com&no_note=1¤cy_code=USD');

my $res = $ua->request($req);
 print "Content-type: text/html\n\n";
print $res->as_string;
-----------------------------------------------------------------------------------
0
 
MercantilumCommented:
If you "use strict" you have to declare locally $ua:

my $ua = LWP::UserAgent->new;
0
 
ziffgoneAuthor Commented:
Mercantilum, SO CLOSE!!!

Your suggestion of declaring it locally worked, but now I face another problem.

The script generates the PayPal page on my server instead of PayPal's. To see
what I mean, check it out:

http://webmastereseller.com/cgi-bin/test_post.cgi

Is there a way I could "Target" the POSTed data to PayPal's
"https://www.paypal.com/cgi-bin/webscr" page instead of having it generated on my server?

Soooo close, I'm going to have to increase the points for this one!
0
 
MercantilumCommented:
Yes, you can automatically simulate a POST of data to paypal.

- I did it with curl, "man curl"  or install it from http://curl.haxx.se/  (curl can be called from Perl)

- In Perl your LWP::UserAgent should be able to do it (just in case: http://www.perldoc.com/perl5.6/lib/LWP/UserAgent.html )

It is actually quite easy when you know the format of the data to be sent (e.g.  user=xxx&password=taratata&... )

If you don't know the format of the post data, and don't know how to get it.
you can simulate a POST using paypal and record all network operations with ethereal http://www.ethereal.com/
This is a fantastic network monitoring tool, it will show you what exactly was sent to paypal when you click the Post button
(You don't need to put actual data for paypal, just to get the format of the post :)

Another thing is about a cookie that could have been set at the beginning of the paypal session, ethereal can tell you that as well
(have to look inside the http frames)
0
 
ziffgoneAuthor Commented:
Quote Mercantilum: "I did it with curl, "man curl"":

Mercantilum, could you send me a script, based upon the variables in
my script above that will work using the "man curl" funtion? The curl function
works on my server, but I keep getting syntax errors.

<email address deleted by COBOLdinosaur, Page Editor, CGI>

I will think up a just reward if you are willing to do this for me.
I'm fairly new to Perl and web programming in general and what
you indicated above for reference at perldoc.com and ethereal.com
seems to be way above my comprehension to implement.

Thanks...
0
 
MercantilumCommented:
"man curl" was for manual curl. On Linux / Unix enter
   man curl
to get the curl help. (or get curl from  http://curl.haxx.se/ )

Extract from the man page:

<<  -d/--data <data>
        (HTTP) Sends the specified data in a POST request to the HTTP server, in a way that  can  emu-
        late  as if a user has filled in a HTML form and pressed the submit button. Note that the data
        is sent exactly as specified with no extra processing (with all newlines cut off).   The  data
        is expected to be "url-encoded". This will cause curl to pass the data to the server using the
        content-type application/x-www-form-urlencoded. Compare to -F.  If  more  than  one  -d/--data
        option  is  used  on  the same command line, the data pieces specified will be merged together
        with a separating &-letter. Thus, using '-d name=daniel -d skill=lousy' would generate a  post
        chunk that looks like 'name=daniel&skill=lousy'.

        If you start the data with the letter @, the rest should be a file name to read the data from,
        or - if you want curl to read the data from stdin.  The contents of the file must  already  be
        url-encoded.  Multiple  files  can  also be specified. Posting data from a file named 'foobar'
        would thus be done with "--data @foobar". >>

So your Perl script can be something like
       ...
      my %data;
      $data{'card'} = "481234567801321";
      $data{'expire'} = "0605";
      $data{'name'} = "Ziff Gone";
      $data{'price'} = "423.28";

Construct the data string

      my $line;
      my @items;
      foreach (keys %data) { push(@items, "$_=$data{$_}"); }
      $line =  join("&", @items);

Output line to a file (in cases of spaces, etc...)

      open F, ">data";
      print F $line;
      close F;

Execute curl and get result in @res

      my @res = `curl -d \@data http://www.paypal.com/something/...`;
      print @res;
0
 
ziffgoneAuthor Commented:
I can't seem to put this all together, just not learned enough in Perl I guess.

Mercantilum, you get the points for your help.

Thanks.
0
 
MercantilumCommented:
What are you getting problem with?
If the perl lines above are the problem it can be fixed.
0
 
ziffgoneAuthor Commented:
With the following script I'm getting the premature end to script headers again:

#!/usr/bin/perl -w

use strict;
use CGI;


use CGI::Carp qw(fatalsToBrowser);

use LWP::UserAgent;
my $ua = LWP::UserAgent->new;

my %data;
      $data{'cmd'} = "_xclick";
      $data{'business'} = "ziffgone\@telus\.net";
      $data{'item_name'} = "MASSIVE Webmaster\&\#39\;s Resale Package";
      $data{'item_number'} = "MWRP001ref=booj\@boogiejack\.com";
      $data{'amount'} = "69\.95";
      $data{'return'} = "http://webmastereseller\.com/**********\.htm";
      $data{'cancel_return'} = "http://webmastereseller\.com";
      $data{'no_note'} = "1";
      $data{'currency_code'} = "USD";

my $line;
      my @items;
      foreach (keys %data) { push(@items, "$_=$data{$_}"); }
      $line =  join("&", @items);

open F, ">data";
      print F $line;
      close F;

my @res = 'curl -d \@data https://www.paypal.com/cgi-bin/webscr';
      print @res;

If I add the >> print "Content-type: text/html\n\n"; << notation before printing, all it does is output:
"curl -d \@data https://www.paypal.com/cgi-bin/webscr" to the screen.

??
0
 
MercantilumCommented:
Oh I see,
1. you need the  print "Content-type: text/html\n\n"
2. and
  my @res = 'curl -d \@data https://www.paypal.com/cgi-bin/webscr';
is actually
  my @res = `curl -d \@data https://www.paypal.com/cgi-bin/webscr`;
using bacquotes `  and not common ' quotes...
0
 
ziffgoneAuthor Commented:
No there is no errors, but it comes up blank? Sorry for troubling you like this.
0
 
MercantilumCommented:
No trouble mate :)
Here to help, and if I'm not in a mood to help, I just close the browser...

Of course your Content-type line is before the print @res...


print "Content-type: text/html\n\n";

# change a bit the options of curl
my @res = 'curl -s -d \@data https://www.paypal.com/cgi-bin/webscr';
print @res;


And try to run the perl script from command line in a shell window, to see what is your output before the web server processed it.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 8
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now