Fall Semester 2007


Week Two: Introduction to Perl and simple CGI scripts written in Perl.
Last week we installed Apache.

We did this on silo, under Unix.

We reviewed some Unix commands in the lab exercise, creating an archive.

Apache is a web server.

Its main purpose is to serve HTML pages, which we place in htdocs.

It can also run programs for our users, programs are to be placed in cgi-bin.

Our programs will be written in Perl.

Minimum Perl that we need to know: variables, lists, hashtables; if, for, foreach.

So we introduced Perl with a program like this:

#!/usr/bin/perl

%contents = ("snickers" => 70, "pretzels" => 50, "soda" => 75);

print "Welcome to the vending machine!\nready> ";

while ($input = <STDIN>) {
  chop($input);
  if ($input eq "quit") { last; }
  elsif ($input =~ /^add\s/) {
    ($add, $what, $price) = split(/ /, $input, 3);
    $contents{$what} = $price;

  } elsif ($input =~ /^\s*show\s+all\s*$/i) {
    foreach $key (keys %contents) {
      $price = sprintf("%4.2f", $contents{$key} / 100);
      print $key, " --> \$", $price, "\n";
    }
  } elsif ($contents{$input}) {
    $price = sprintf("%4.2f", $contents{$input} / 100);
    print $input, " costs \$$price\n";
  } else {
    print "I don't understand $input, sorry.\n";
    print "Try: show all, add <product> <cents>, <product>, or quit\n";
  }
  print "ready> ";
}
Run this program, play with it, think about it, annotate the code.

The simplest meaningful CGI script was like this:

#!/usr/bin/perl

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

$time = localtime;

print "The time now is: ", $time, "\n";
We talked about HTTP always requiring this structure: headers, empty line, body (data, if any)

So that's the first major difference between a program you run at the Unix prompt and a web script: the web script sends data to a browser and therefore needs to notify the browser first what kind of data it is sending, so the browser can process (render, etc.) the data accordingly.

Now we look in cgi-bin and we find a printenv program there.

Create a form in htdocs in a file and point it to printenv:

<html>
  <head><title>Form example with CGI</title></head>
  <body>
    <form action="/cgi-bin/printenv">
      <table>
        <tr> <td> Username
             <td> <input type="text"     name="uname" size=8>
        <tr> <td> Password
             <td> <input type="password" name="pword" size=12>
      </table>
      <p> Press <input type="submit" value="Proceed"> to submit data.
    <form>
  </body>
</html>
Type abc for the username and elephant for the password.

Once you submit take a look at how the URL changes.

On the screen that printenv writes back look for the QUERY_STRING entry.

So %ENV is available by default to a script and it can help us feed data in the program.

The data might need to be somewhat parsed.

Change the form to point to a new web script we will write, process:

<html>
  <head><title>Form example with CGI</title></head>
  <body>
    <form action="/cgi-bin/process">
      <table>
        <tr> <td> Username
             <td> <input type="text"     name="uname" size=8>
        <tr> <td> Password
             <td> <input type="password" name="pword" size=12>
      </table>
      <p> Press <input type="submit" value="Proceed"> to submit data.
    <form>
  </body>
</html>
Then write process and place it in cgi-bin:
#!/usr/bin/perl

print "Content-type: text/html\n\n<html><head><title>Whatever...</title>";
print "</head><body bgcolor=\"white\">"; # should have used print qq{ ...

$input = $ENV{"QUERY_STRING"};

@pairs = split(/&/, $input);

foreach $pair (@pairs) {
  ($name, $value) = split(/=/, $pair);
  $form{$name} = $value;
}

foreach $key (keys %form) {
  print $key, " --> ", $form{$key}, "\n<p>";
}

print "</body></html>";
Run this to see how we can get our hands on the data.

Now it's time for some exercises:

Let me know if you experience any difficulties.


Last updated: Sep 6, 2007