CSCI A348/A548

Lecture Notes 6

Fall 1999


In which we define CGI and take a look at CGI processing with request method GET.

We start by creating a directory lecture6 in cgi-bin. All the scripts that we will be writing today will go in there (although only some will be called from over the web). The first program we write will be called one, and we do not intend to run from over the web. Its purpose is to illustrate command line arguments: they are a way of feeding data into a program when you start the program. This mechanism is built-in, and to use it you simply need to know about it and follow its conventions.

The program also illustrates the foreach construct, and compares it with the more common for.

#!/usr/bin/perl
 
foreach $arg (@ARGV) {
  print " $arg\n"; 
} 
 
for ($i = 0; $i <= $#ARGV; $i++) {
  print $i, ": ", $ARGV[$i], "\n"; 
}
We then write this script called two, which produces a menu of options. It also checks the command line argument it was started with (and reports if none was provided) and if it matches one of the options it displays that option differently in the menu. This very much looks like your homework.

You notice that there's only one script with five versions of output.

Again, we only run this from the command line.

#!/usr/bin/perl
 
if ($#ARGV >= 0) {
  $one = "<Option 1>"; 
  $two = "<Option 2>"; 
  $three = "<Option 3>"; 
  if ($ARGV[0] eq "one") {
    $one = " Option1*";  
  } elsif ($ARGV[0] eq "two") {
    $two = " Option2*";  
  } elsif ($ARGV[0] eq "three") {
    $three = " Option3*"; 
  } else {
    # default behaviour? error message?  
    # no args behaviour be included here? 
  } 
  print qq{ Welcome to two's menu: 
    $one
    $two 
    $three 
  }; 
} else { 
  print " Called with no arguments.\n"; 
}
If you try to access this from over the web you obtain an error. Do you remember why that happens?

We then write this script, called three. It simulates the Unix utility webster and shows what a hashtable is and how we could use it. Unlike a list the indexing is done by strings, also known as keys, which are case sensitive and must match exactly.

#!/usr/bin/perl
 
$DEF{"bandicoot"} = qq{
ban-di-coot \'ban-di-,k:ut\ n
 
1: any of several very large rats (Nesokia and related genera) of
     India and Ceylon destructive to rice fields and gardens
2: any of various small insectivorous and herbivorous marsupial mammals
     family Peramelidae) of Australia, Tasmania, and New Guinea 
}; 
 
$DEF{"jerboa"} = qq{
jer-boa \jer-'bo^--e, jer-\ n
 
:any of several social nocturnal Old World jumping rodents (family
     Dipodidae) with long hind legs and long tail 
 
};  
 
$DEF{"suslik"} = qq{
su-slik \'s:u-slik\ n
 
1:any of several rather large short-tailed ground squirrels (genus Citellus)
     of eastern Europe or northern Asia
2: the mottled grayish black fur of a suslik 
};  
 
$word = $ARGV[0]; 
 
if ($word ne "") { 
  if ($DEF{$word}) {
    print $DEF{$word}; 
  } else {
    print "No definition found for $word\n"; 
  }  
} else {
  print "Called with no arguments.\n"; 
}
To get through the elements of a list one could use for and foreach. To get through the elements of a hashtable one needs to create a list of the keys in that hashtable (using the keys operator first) and then get through that list, as the next example shows. This next example, called four, also shows what it takes to make a script into a CGI script (remember that our output is being sent to a browser), and does it with the help of two procedures, that are defined at the end of the file: header and trailer. We also see how the procedures are invoked (&).

#!/usr/bin/perl
 
&header;
foreach $key (keys %ENV) {
  print $key, ": ", $ENV{$key}, "<br>"; 
} 
&trailer; 
 
sub header {
  print "Content-type: text/html\n\n<html>" . 
        "<head><title>four: prints ENV</title>" .
        "</head><body>\n"; 
} 
 
sub trailer {
  print "\n</body></html>"; 
}
This being a CGI script we can access it. (We should take some time to examine its output.)

We define CGI, the Common Gateway Interface.

We also try out the script by typing its URL followed by a question mark (?) and a string of characters, and watch what is being reported at QUERY_STRING.

For example:

and watch what's being reported in QUERY_STRING.

We then work a little bit more on the output of the program.

This program is providing the user with the built-in capability exemplified above. (So you can click on the three links and start it with three different quesry strings). Notice however that the output is always the same.

#!/usr/bin/perl
 
$qs = $ENV{"QUERY_STRING"}; 
 
%DICT = (
  "SERVER_PORT" => "<a href=\"" . $ENV{"SCRIPT_NAME"} . "\">SERVER_PORT</a>", 
  "SERVER_NAME" => "<a href=\"" . $ENV{"SCRIPT_NAME"} . "\">SERVER_NAME</a>", 
  "SCRIPT_NAME" => "<a href=\"" . $ENV{"SCRIPT_NAME"} . "\">SCRIPT_NAME</a>", 
); 
 
&header;
foreach $key (keys %ENV) {
  if ($DICT{$key}) {
    print $DICT{$key}, ": ", $ENV{$key}, "<br>"; 
  } else { 
    print $key, ": ", $ENV{$key}, "<br>"; 
  } 
} 
&trailer; 
 
sub header {
  print "Content-type: text/html\n\n<html>" . 
        "<head><title>five - prints ENV</title>" .
        "</head><body>\n"; 
} 
 
sub trailer {
  print "\n</body></html>"; 
} 
We then write six.
#!/usr/bin/perl
 
$qs = $ENV{"QUERY_STRING"}; 
 
%DICT = (
  "SERVER_PORT" => "<a href=\"" . $ENV{"SCRIPT_NAME"} . "\">SERVER_PORT</a>", 
  "SERVER_NAME" => "<a href=\"" . $ENV{"SCRIPT_NAME"} . "\">SERVER_NAME</a>", 
  "SCRIPT_NAME" => "<a href=\"" . $ENV{"SCRIPT_NAME"} . "\">SCRIPT_NAME</a>", 
); 
 
&header;
foreach $key (keys %ENV) {
  if ($DICT{$key}) {
    if ($qs eq $key) {
      print "<b>$key</b>: ", $ENV{$key}, "<br>\n"; 
    } else {
      print $DICT{$key}, ": ", $ENV{$key}, "<br>\n"; 
    } 
  } else { 
    print $key, ": ", $ENV{$key}, "<br>\n"; 
  } 
} 
&trailer; 
 
sub header {
  print "Content-type: text/html\n\n<html>" . 
        "<head><title>five - prints ENV</title>" .
        "</head><body>\n"; 
} 
 
sub trailer {
  print "\n</body></html>"; 
} 
Now we make a change just as we did in the script called three.

#!/usr/bin/perl
 
$qs = $ENV{"QUERY_STRING"}; 
$myURL = $ENV{"SCRIPT_NAME"};   
 
%DICT = (
  "SERVER_PORT" => "<a href=\"" . $myURL . "?SERVER_PORT\">SERVER_PORT</a>", 
  "SERVER_NAME" => "<a href=\"" . $myURL . "?SERVER_NAME\">SERVER_NAME</a>", 
  "SCRIPT_NAME" => "<a href=\"" . $myURL . "?SCRIPT_NAME\">SCRIPT_NAME</a>", 
); 
 
&header;
foreach $key (keys %ENV) {
  if ($DICT{$key}) {
    if ($qs eq $key) {
      print "<b>$key</b>: ", $ENV{$key}, "<br>\n"; 
    } else {
      print $DICT{$key}, ": ", $ENV{$key}, "<br>\n"; 
    } 
  } else { 
    print $key, ": ", $ENV{$key}, "<br>\n"; 
  } 
} 
&trailer; 
 
sub header {
  print "Content-type: text/html\n\n<html>" . 
        "<head><title>five - prints ENV</title>" .
        "</head><body>\n"; 
} 
 
sub trailer {
  print "\n</body></html>"; 
}
The resulting program behaves very much like your homework assignment 2 is supposed to.

You should be in good shape to finish it quickly now.

You should also have a good understanding at least one way in which data that is specified by the user can be passed to a CGI script with method GET and what CGI essentially is.

Next week we will explore HTML with forms and how data entered in forms can be passed to CGI scripts using both method GET as well as another request method: POST.


Last updated: September 16, 1999 by Adrian German