I have created a simple HTML and Perl test to figure out how to properly get a browser to re-Post form data to a new URL. The raison d'etre for this test is to figure out the best way to re-Post the shopping cart order form data to PayPal after my Perl script has saved the order etc information to a database.

The test consists of three simple files: 1) an HTML file containing a form, 2) a Perl script called by the form which performs the redirection to 3) a Perl script which displays the form data.

Where I am at now is when I only use

print ("Location: http://briarhilldesign.com/cgi-bin/showdata.pl\n");
print ("Content-type: text/html\n\n");

I get redirected to the final Perl script but with no data. When I also use an HTTP redirection status line, e.g., print("HTTP/1.0 303 See Other\n"); I get an Internal Server Error:

Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator, webmaster@briarhilldesign.torontogardenbook.com and inform them of the time the error occurred, and anything you might have done that may have caused the error.
More information about this error may be available in the server error log.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
Apache/2.2.11 (Unix) mod_ssl/2.2.11 OpenSSL/0.9.8i DAV/2 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 Server at briarhilldesign.com Port 80

Here is the code for the three files.

redirect.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
  <title>HTML redirect test</title>
  <style>
    input#submit {
      display: block;
}
  </style>
</head>

<body>
  <form id="redirect-form" action="http://briarhilldesign.com/cgi-bin/redirect.pl" method="post">
    <fieldset>
      <legend>Data to redirect</legend>
      <label for="first_name">First Name</label><input id="first_name" name="first_name" value="John" />
      <label for="last_name">Last Name</label><input id="last_name" name="last_name" value="Smith" />
      <h3>Choose the redirect method:</h3>
     	<input type="radio" id="none" name="redirect-method" value="none" /><label for="location">No code</label>
     	<input type="radio" id="300" name="redirect-method" value="300" /><label for="300 multiple choices">300 multiple choices</label>
     	<input type="radio" id="301" name="redirect-method" value="301" /><label for="301 moved permanently">301 moved permanently</label>
     	<input type="radio" id="302" name="redirect-method" value="302" /><label for="302 found">302 found</label>
     	<input type="radio" id="303" name="redirect-method" value="303" /><label for="303 see other">303 see other</label>
     	<input type="radio" id="307" name="redirect-method" value="307" /><label for="307 temporary redirect">307 temporary redirect</label>
      <input type="submit" id="submit"/>
    </fieldset>
  </form>  
</body>

</html>

In this HTML file one chooses from six possible kinds of redirection.


redirect.pl

#!/usr/local/bin/perl -w
# redirect.pl -- redirects to showdata.pl using the indicated method
BEGIN {my $homedir = ( getpwuid($>) )[7];my @user_include;foreach my $path (@INC) { if ( -d $homedir . '/perl' . $path ) 
  {push @user_include, $homedir . '/perl' . $path;}} unshift @INC, @user_include;}
use warnings;
use strict;
use CGI qw(:standard);
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);

my $form1 = new CGI;
my $RedirectMethod = $form1->param('redirect-method');

for ($RedirectMethod) {
  if (/none/) {} # No code sent
  if (/300/)  {print("HTTP/1.0 300 Multiple Choices\n");}
  if (/301/)  {print("HTTP/1.0 301 Moved Permanently\n");}
  if (/302/)  {print("HTTP/1.0 302 Found\n");}
  if (/303/)  {print("HTTP/1.0 303 See Other\n");}
  if (/307/)  {print("HTTP/1.0 307 Temporary Redirect\n");}
}

# Rest of HTTP Response
print ("Location: http://briarhilldesign.com/cgi-bin/showdata.pl\n");
print ("Content-type: text/html\n\n");

# TRY am HTML body here later, if necessary
print q~<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
  <title>You are being redirected</title>
</head>

<body>
  <h1>Redirection</h1>
  <p>You are being redirected. Version 11.</p>
</body>
</html>
~;

This Perl script performs one of six different kinds of redirection depending on the value of the form variable 'redirect-method'.


showdata.pl

#!/usr/local/bin/perl -w
# showdata.pl -- displays form data
BEGIN {my $homedir = ( getpwuid($>) )[7];my @user_include;foreach my $path (@INC) { if ( -d $homedir . '/perl' . $path ) 
  {push @user_include, $homedir . '/perl' . $path;}} unshift @INC, @user_include;}
use warnings;
use strict;
use CGI qw(:standard);
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);

my $form1 = new CGI;
my $FirstName = $form1->param('first_name');
my $LastName = $form1->param('last_name');
my $RedirectMethod = $form1->param('redirect-method');


print (qq~Content-Type: text/html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
  <title>HTML redirect test</title>
</head>

<body>
  <h1>Data received</h1>
  <p>First Name: $FirstName</p>
  <p>Last Name: $LastName</p>
  <p>Redirect Method: $RedirectMethod</p>
</body>

</html>
~);

This Perl script displays the form data passed to it.


Any help getting the HTTP status line to work so I can redirect and induce the browser to re-Post the data it has just posted would be greatly appreciated.

You can't get the data sent to redirect.pl parsed by showdata.pl the way you are trying.

You have to recieve the data in your redirect.pl script and save it to disk and have showdata.pl open the file and get the data from a file or send the data to showdata.pl the same way the html form does, using POST or GET methods. You can use a module like LWP::UserAgent to send data from one CGI script to another. But if both scripts run on the same server you probably want to look into CGI::Sessions or maybe there are newer modules by now.

Comments
Great Answer!

Thank you very much, KevinADC. I will look at those CPAN PayPal modules.

I had been using LWP::UserAgent to Post data but I am ultimately doing this test to prepare a system for PayPal. What I found was Posting with LWP::UserAgent and printing the returned HTML results leaves my Perl script's URL in the browser address bar instead of the PayPal URL. That's why I was trying to use a redirect.

Maybe someone else will have a suggestion. I think I have offered all I can at this point.

Good luck

It would seem to me that you would want a server process to post to paypal and have your client process wait for notification that the paypal server transaction completed. That's what I would do. The server process, which could run as a script that is CRONed, but it would be better IMO to have an internal listener that waits for your client to connect and requests the paypal transaction. You server would talk to paypal, get status and reply to your client program, which would in turn contact the browser with status. You can do this in any language and perhaps you can use the CPAN paypal modules on the server side and the LWP modules on the client side, either re-loading the page or making the browser wait until the status is returned.

I'm not trying to be a pain as an architect here, especially since you have already poured the foundation, but I think you might get more consistent results from an (internal) client/server setup.

Thank you mitchems for that detailed suggestion. I must admit some of the technologies you mentioned I'm not familiar with.

As KevinADC mentions, and I am learning, PayPal has SOAP APIs that allow a developer to process credit cards from his own html page. This is something along the lines your were describing I think, mitchems.

So I think that is what I will do. I will learn the PayPal SOAP stuff and process credit cards and PayPal payments as part of my own checkout form. This seems to be the most elegant approach. A good skill to have that I can use on many sites once I know it.

This article has been dead for over six months. Start a new discussion instead.