CGI is shorter for ‘Common Gateway Interface’. CGI is component running on web servers
and acts as an interface to database, documents and other applications. It receives
requests from users (web browsers), performs tasks and returns the result back to the user.
CGI can be written in many programming languages. Most widely used and most suitable
language for writing cgi scripts is Perl. Most UNIX based systems support it.
CGI invokes .cgi script, which calls the program in which it was written and interprets
the code.
Since HTML is used for representation of data in web browsers only, CGI might be the next
step, because it enables more interactions between end user and web server. CGI is needed
to create guest books, counters, forms and interactive charts within your web page.
Get started
For beginning let’s make an example how CGI and Perl are involved in the process of HTTP request.
CGI script is nothing more than ordinary text file. This is first exmple:
#! /usr/bin/perl
use CGI qw(:standard);
print header;
print "Hello World";
First line tells the interpreter which program will be used for execution - perl.
Next line imports CGI’s standard library, which holds some useful functions.
‘print’ functions are used to display data in web browser.
Copy the text above in file first.cgi and upload the file to your web server in
/cgi-bin/mycgi/ directory. CGI scripts must have its file permissions set to 755
(or at least all users should have execute privileges).
Script can be easiliy started from your web browser:
http://www.yourdomain.com/cgi-bin/mycgi/first.cgi
Click here to execute my first.cgi script.
New window should appear saying ‘Hello world’ if cgi script was compiled and
executed correctly.
Setting up CGI environment is out of scope of this tutorial, if you need help call
your server administrator.
When sending response back to user, CGI script creates html response with all
necessary tags. Another example:
#!/usr/bin/perl -wT
print "Content-type: text/html\n\n";
print "<html><head><title>Hello World</title></head>\n";
print "<body>\n";
print "<h2>Hello, world!</h2>\n";
print "</body></html>\n";
Into Perl
This section covers basics of Perl: declaring variables, arrays, hashtables and some basic operations upon them.
Remember that cgi scripts should always start with:
#! /usr/bin/perl -wT
use CGI qw(:standard);
print header;
Strings
Declaring and using strings:
my $string = 'dummy string';
print "some $string\n";
my $stringLength = length($string);
print “String: $string has length: $stringLength\n”;
Join strings together:
my $S1 = 'string';
my $S2 = ' is ';
my $S3 = 'long';
print “$S1.S2.$S3\n";
Directly insert piece of html code into document:
print <<TEXT_TO_PRINT;
This is my text. Send me yours if you want.<p>
<a href="mailto:name@somewhere.com">send me an email!</a></p>
TEXT_TO_PRINT
Integers
Declaring and using integers:
my $int1 = 1;
my $int2 = 2;
my $sum = $int1 + $int2;
$sum++;
print $sum;
Arrays
Declaring and using arrays:
my @colors = ("red", "green", "blue");
print $colors[0]."\n";
print $colors[1]."\n";
print $colors[2]."\n";
push(@ colors, 'cyan');
push(@ colors, ('black', 'white'));
my $numberOfColors = scalar(@ colors);
print "array of colors contains $numberOfColors elements";
Iterating over array:
foreach my $i (@ colors) {
print "$i\n";
}
# or
foreach my $i (0..$#colors) {
print "color $i is $colors[$i]\n";
}
Get first element:
my $first = shift(@colors);
Get last element:
my $last = pop(@colors);
# or
my $last = $colors[$#colors];
where $#colors is equivalent to scalar(@colors)-1.
Slicing arrays:
my @slice = @colors[1..2];
Sort alphabetically:
my @sortedColors = sort(@colors);
Sorting numbers (alphabetically 12 is before 2, but not numerically):
my @numberList = (3, 1, 8, 5);
my @sortedNumberList = sort( {$a <=> $b;} @numberList);
Invert order of elements:
my @invertedColors = reverse(@colors);
Join elements into single string:
my $colorString = join(", ",@colors);
print $colorString;
Hashtables
Declaring and using hashtables:
my %hashTable;
$hashTable{'name1'} = 'John';
$hashTable{'name2'} = 'Frank';
$hashTable{'name3'} = 'Rachel';
print $hashTable{'name1'}."\n";
while (my($key, $value) = each(%hashTable))
{
print $key.' - '.$value."\n";
}
if (exists $hashTable{1})
{
print "name1 exists in hashtable";
}
else
{
print "name1 does not exist in hashtable";
}
Adding items:
$hashTable{name4} = “Samuel”;
Get hashtable size:
my $hashTableSize = scalar keys(%hashTable);
print "hashtable size: ".$hashTableSize;
Delete entry:
delete $hashTable{key2};
Delete all entries:
%hashTable = ();
Loops
While loop:
my $integer = 0;
while($integer < 5)
{
print $integer."\n";
$integer++;
}
For loop (I see no output from this for loop ???):
for(my $c = 0; $c++; $c < 10)
{
print $c."\n";
}
Iterators:
my @colors = ("red","green","blue");
foreach my $i (@colors) {
print "$i\n";
}
Conditions
my $number = 99;
if($number eq 99)
{
print 'number is exactly 99';
}
else
{
print 'number is NOT 99';
}
if($number eq 99)
{
print 'number is exactly 99';
}
elsif($number eq 100)
{
print 'number is exactly 100';
}
else
{
print 'number is NOT 99, NEITHER 100';
}
my $name = 'Matjaz';
if($name eq 'Matjaz')
{
print 'You are the boss!';
}
unless($name eq 'matjaz')
{
print 'What a freak...';
}
This is basically all you need to know about Perl for now. Now, let’s focus on CGI.
CGI is back
Environment variables is hashtable with keys and values which web server sends to CGI program.
DOCUMENT_ROOT The root directory of your server
HTTP_COOKIE The visitor's cookie, if one is set
HTTP_HOST The hostname of the page being attempted
HTTP_REFERER The URL of the page that called your program
HTTP_USER_AGENT The browser type of the visitor
HTTPS "on" if the program is being called through a secure server
PATH The system path your server is running under
QUERY_STRING The query string (see GET, below)
REMOTE_ADDR The IP address of the visitor
REMOTE_HOST The hostname of the visitor (if your server has
reverse-name-lookups on; otherwise this is the IP address again)
REMOTE_PORT The port the visitor is connected to on the web server
REMOTE_USER The visitor's username (for .htaccess-protected pages)
REQUEST_METHOD GET or POST
REQUEST_URI The interpreted pathname of the requested document or CGI
(relative to the document root)
SCRIPT_FILENAME The full pathname of the current CGI
SCRIPT_NAME The interpreted pathname of the current CGI (relative to the
document root)
SERVER_ADMIN The email address for your server's webmaster
SERVER_NAME Your server's fully qualified domain name
SERVER_PORT The port number your server is listening on
SERVER_SOFTWARE The server software you're using (e.g. Apache 1.3)
This is example of script, which prints all environment variables:
#!/usr/bin/perl -wT
use strict;
use CGI qw(:standard);
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
print header;
print start_html("Environment");
foreach my $key (sort(keys(%ENV))) {
print "$key = $ENV{$key}<br>\n";
}
print end_html;
Here are my environment variables.
GET function
To send user data to server, you can use two methods: GET and POST. The values which
are sent can be filled in a form. Paste the following html code to your web page:
<form action="someScript.cgi" method="GET">
ID: <input type="text" name="id" size=30><p>
Name: <input type="text" name="name" size=30><p>
<input type="submit">
</form>
With GET function, the input values are sent as part of url address like this:
http://www.matjazcerkvenik.si/cgi-bin/someScript.cgi?id=123&name=John
Two parameters are sent to CGI program: id and name. The parameters are sent in
QUERY_STRING environment variable.
Get single parameter from QUERY_STRING:
my $id = param('id');
my $name = param('name');
Get all parameters at once (array):
my @fieldnames = param();
Because all parameters are sent as part of the url, GET method is definitely not the
safest one. It is strongly recomended that sensitive data (passwords, user IDs...)
is not sent in url. In such cases it is better to use POST method. All you need to do
is modify method (from GET to POST) inside html form. The rest is done by CGI.pm library.
Guestbook example
Paste the following html form in one of your pages:
<form action="http://www.matjazcerkvenik.si/cgi-bin/mycgi/guestList.cgi"
method="POST">
Name: <input type="text" name="name"> <br>
E-mail: <input type="text" name="email"> <br>
Comment: <textarea name="comment" cols=35 rows=4>Are you moonwalker?
</textarea> <br>
<input type="submit" value="Submit">
</form>
Make a Perl script that reads all text fields from the form, and reads two environment
variables: remote address and type of web browser. Then store this data into file.
#! /usr/bin/perl
use CGI qw(:standard);
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
use strict;
print header;
open(FILEHANDLE, ">>./guestList.txt") || die('cannot open file: '.$!);
my $name = param('name');
my $email = param('email');
my $comment = param('comment');
my $hostname = $ENV{REMOTE_ADDR};
my $browser = $ENV{HTTP_USER_AGENT};
print FILEHANDLE "Name: $name\nEmail: $email\nHostname: $hostname\nBrowser: $browser\nComment: $comment\n--------------------------------------------\n";
close(FILEHANDLE);
print start_html("Guest List");
print "Pozdravljen $name <br><br>";
print "<a href=\"http://www.matjazcerkvenik.si\">home</a>";
print end_html;