CGI Programming

So you're gathering information from your surfers; what now?
Bringing It All Together

The final version of the program, with (a) required fields, (b) full-English descriptions of those fields, and (c) a better error message when we cannot open the file, reads as follows:

#!/usr/local/bin/perl5
# We want to use the CGI module
use CGI;
# Set the filename to which we want the elements
# saved
my $filename = "/tmp/formcontents";
# Set the character that will separate fields in
# the file
my $separation_character = "\t";
# In what order do we want to print fields?
my @fields = ("name",
              "email",
              "address",
              "country",
              "sex");
# Which fields are required?
my @required_fields = ("name",
                       "email",
                       "address");
# What is the full name for each required field?
$FULLNAME{"name"} = "your full name";
$FULLNAME{"email"} = "your e-mail address";
$FULLNAME{"address"} = "your mailing address";
# Create a new CGI object
my $query = new CGI;
# ---------------------------------------------
# Make sure that all required fields have arrived
foreach $field (@required_fields)
{
    # Add the name of each missing field
    push (@missing_fields, $field)
    if ($query->param($field) !~ m/\w/);
}
# If any fields are missing, invoke the error
# routine
&missing_field(@missing_fields)
  if @missing_fields;
# ---------------------------------------------
# Open the file for appending
  open (FILE, "7gt;>$filename") ||
  &error_opening_file($filename);
# Grab the elements of the HTML form
@names = $query->param;
# Iterate through each element from the form,
# writing each element to $filename. Separate
# elements with $separation_character defined
# above.
foreach $index (0 .. $#fields)
{
    # Get the input from the appropriate HTML
    # form element
    $input = $query->param($fields[$index]);
    # Remove any instances of
    # $separation_character
    $input =~ s/$separation_character//g;
    # Now add the input to the file
    print FILE $input;
    # Don't print the separation character after
    # the final element
    print FILE $separation_character if
    ($index < $#fields);
}
# Print a newline after this user's entry
print FILE "\n";
# Close the file
close (FILE);
# ---------------------------------------------
# Now thank the user for submitting their
# information
# Print an a appropriate MIME header
print $query->header("text/html");
# Print a title for the page
print $query->start_html(-title=>"Thank you");
# Print all of the name-value pairs
print "<P>Thank you for submitting ";
print "the form.</P>\n";
print "<P>Your information has been ";
print "saved to disk.</P>\n";
# Finish up the HTML
print $query->end_html;
# ---------------------------------------------
# Subroutines
sub missing_field
{
    # Get our local variables
    my (@missing_fields) = @_;
    # Print an a appropriate MIME header
    print $query->header("text/html");
    # Print a title for the page
    print $query->start_html(-title=>
    "Missing field(s)");
    print "<P>You are missing the following
    required fields:</P>\0";
    print "<ul>\n";
    # Iterate through the missing fields,
    # printing them
    foreach $field (@missing_fields)
    {
        print "<li> $FULLNAME{$field}\n";
    }

    print "</ul>\n";

    print "</ul>\n";

    # Finish up the HTML
    print $query->end_html;

    exit;
}
sub error_opening_file
    {
        my ($filename) = @_;
        # Print an a appropriate MIME header
        print $query->header("text/html");
        # Print a title for the page
        print $query->start_html(-title=>
        "Error opening file");
        # Print the error
        print "Could not open the file
        \"$filename\".</P>\n";
        # Finish up the HTML
        print $query->end_html;
        exit;
    }
Creating a Guest-book

One of the most common CGI applications on the Web is a “guest-book”, which allows visitors to a site to sign in, leaving their names, e-mail addresses and short notes. We can easily construct such a program, using the basic framework seen in the above programs. The only difference between the “guestbook” program and the programs we have seen so far is that the guest-book must be formatted in HTML in order for users to be able to read it in their browsers.

Here is a very simple guest-book program that is virtually the same as the previous program we saw:

<HTML>
<Head>
<Title>Guestbook entry</Title>
</Head>
<Body>
<H1>Guestbook entry</H1>
<Form action="/cgi-bin/guestbook.pl"
    method=POST>
<P>Name: <input type=text name="name"
    value=""></P>
<P>E-mail address: <input type=text name="email"
value=""></P>
<input type=submit>
</Form>
</Body>
</HTML>

The following program is the same as the one above, except that it saves data to the “guestbook.html” and formats the data in HTML.

#!/usr/local/bin/perl5
# We want to use the CGI module
use CGI;
# Set the filename to which we want the elements
# saved
my $filename =
"/home/reuven/Consulting/guestbook.html";
# Set the character that will separate fields in
# the file
my $separation_character = "</P><P>";
# In what order do we want to print fields?
my @fields = ("name", "email");
# Which fields are required?
my @required_fields = ("name", "email");
# What is the full name for each required
# field?
$FULLNAME{"name"} = "your full name";
$FULLNAME{"email"} = "your e-mail address";
# Create a new CGI object
my $query = new CGI;
# ---------------------------------------------
# Make sure that all required fields have arrived
foreach $field (@required_fields)
{
  # Add the name of each missing field
  push (@missing_fields, $field) if
  ($query->param($field) !~ m/\w/);
}
# If any fields are missing, invoke the error
# routine
&missing_field(@missing_fields) if
  @missing_fields;
# ----------------------------------------------
# Open the file for appending
open (FILE, ">>$filename") ||
  &error_opening_file($filename);
# Grab the elements of the HTML form
@names = $query->param;
# Iterate through each element from the form,
# writing each element to $filename. Separate
# elements with $separation_character defined
# above.
foreach $index (0 .. $#fields)
{
  # Get the input from the appropriate HTML form
  # element
  $input = $query->param($fields[$index]);
  # Remove any instances of $separation_character
  $input =~ s/$separation_character//g;
  # Now add the input to the file
  print FILE $input;
  # Don't print the separation character after the
  # final element
  print FILE $separation_character if
  ($index < $#fields);
}
# Print a newline after this user's entry
print FILE "<BR><HR><P>\n\n";
# Close the file
close (FILE);
# -------------------------------------------
# Now thank the user for submitting his
# information
# Print an a appropriate MIME header
print $query->header("text/html");
# Print a title for the page
print $query->start_html(-title=>"Thank you");
# Print all of the name-value pairs
print "<P>Thank you for submitting ";
print "the form.</P>\n";
print "<P>Your information has been ";
print "saved to disk.</P>\n";
# Finish up the HTML
print $query->end_html;
# --------------------------------------------
# Subroutines
sub missing_field
{
  # Get our local variables
  my (@missing_fields) = @_;
  # Print an a appropriate MIME header
  print $query->header("text/html");
  # Print a title for the page
  print $query->start_html(-title=>"
  Missing field(s)");
  print "<P>You are missing the ";
  print "following required fields:</P>\n";
  print "<ul>\n";
  # Iterate through the missing fields, printing
  # them
  foreach $field (@missing_fields)
    {
        print "<li> $FULLNAME{$field}\n";
        }
  print "</ul>\n";
  print "</ul>\n";
  # Finish up the HTML
  print $query->end_html;
  exit;
}
sub error_opening_file
{
  my ($filename) = @_;
  # Print an a appropriate MIME header
  print $query->header("text/html");
  # Print a title for the page
  print $query->start_html(-title=>
  "Error opening file");
  # Print the error
  print "Could not open the ";
  print "file \"$filename\".</P>\n";
  # Finish up the HTML
  print $query->end_html;
  exit;
}

The above program will take input from the HTML form and save the data in an HTML-formatted file. If that file is accessible from the web server, your users should be able to view others' entries in the guest-book.

Reuven M. Lerner (reuven@the-tech.mit.edu) (reuven@netvision.net.il) has been playing with the Web since early 1993, when it seemed like more of a fun toy than the world's Next Great Medium. He currently works from his apartment in Haifa, Israel as an independent Internet and Web consultant. When not working on the Web or informally volunteering with school-age children, he enjoys reading (just about any subject, but especially computers, politics, and philosophy—separately and together), cooking, solving crossword puzzles and hiking.

______________________

White Paper
Fabric-Based Computing Enables Optimized Hyperscale Data Centers

Today’s modular x86 servers are compute-centric, designed as a least common denominator to support a wide range of IT workloads. Those generic, virtualized IT workloads have much different resource optimization requirements than hyperscale and cloud applications. They have resulted in a “one size fits all” enterprise IT architecture that is not optimized for a specific set of IT workloads, and especially not emerging hyperscale workloads, such as web applications, big data, and object storage. In this report, you will learn how shifting the focus from traditional compute-centric IT architectures to an innovative disaggregated fabric-based architecture can optimize and scale your data center.

Learn More

Sponsored by AMD

White Paper
Red Hat White Paper: Using an Open Source Framework to Catch the Bad Guy

Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6

Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.

Learn more about catching the bad guy in this free white paper.

Learn More

Sponsored by DLT Solutions