Lesson Three

Contact:http://www.packetnexus.com

Lesson Three: CGI Applications

One of the coolest uses of Perl is for CGI Applications on Web sites.
Typically, HTML is static. You write up the HTML file, you put it on your
Web server, and people download it and look at it. Well, wouldn't it be nice
if that little HTML file had some dynamic element to it, such as "today's
date"? Well, never fear, we're going to do just that!

Because this is Maximum Linux, and just about every Linux machine in
existence has the Apache Web Server on it, we're going to assume that you
have Apache set up and executable files ending in ".cgi" are run as CGI
programs. Consider the following code (although, this time, save it as
"sample.cgi" and place it where you can get to it via the Web).

#!/usr/bin/perl
print "Content-type: text/html\n\n";

$time = localtime ( time );
print "Today: $time\n";

In this script, we print a legal CGI header (Content-type: text/html\n\n)
and then call localtime ( time ) in a scalar context. (That is to say, we
call localtime as if it were a variable.) Next we simply print the string
"Today:"and then whatever localtime gave us. Some sample output of this
program might look like this:

Content-type: text/html

Today: Fri Apr 28 02:26:37 2000

Notice the \n\n after the Content-type line. This is very important, as it
signifies the end of the HTML header and the beginning of the content. When
the Web browser renders this, it won't render Content-type…just Today: Fri
Apr 28 02:26:37 2000.

Let's make a completely server-generated page that parses an HTML file and
inserts the date wherever it sees ##date. If we have some HTML in a file
called sample.inc that looks like this:


Welcome:##date

  Today's date is ##date.



and we have the following script named sample.cgi:

#!/usr/bin/perl

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

$date = localtime ( time );

open (FILE, "sample.inc") or die "Can't open sample.inc\n";
while ( ) {
  s/##date/$date/g;
  print
}
close ( FILE );

Now when we hit sample.cgi in a Web browser, we should get the contents of
the include file (sample.inc) printed out with every instance of ##date
replaced with today's date. Of course, you don't want to do this on a
heavily hit Web server, because parsing every single line of HTML takes
time, but it's still a great example.

So that's cool, but what about forms? Now that's where the real fun comes
in! Consider the following code with the subroutine "parse." Form data shows
up as if it were typed on the command line (STDIN) to a CGI application.
This little routine will grab the data from STDIN and set it up in a nice
handy format.

#!/usr/bin/perl

parse ( );

print "Content-type: text/html\n\n";
print "\n";
print "Your name is $cgi{'name'}\n";
print "and your email is $cgi{'email}\n";
print "\n";

sub parse {
  read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
  @pairs = split(/&/, $buffer);
  foreach $pair (@pairs)
  {
    ($name, $value) = split(/=/, $pair);
    $value =~ tr/+/ /;
    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
    $cgi{$name} = $value;
  }
}

And we'll access this CGI program from a form that asks for some input:



Name:
Email:
Now, when the user hits the HTML page and enters some data, we will have access to it in the hash called $cgi{}. So to access what the person typed in for the name field, it is referenced as the variable $cgi{'name'}. The inner workings of the parse subroutine are a little beyond this Perl primer, but at least it