WebHints: Mechanics: CGI/PERL

When you request an ordinary HTML page such as index.html, the webserver simply fetches the page and returns it to your browser, which displays the page.

However, if you request a file that is an executable program, the server executes the program and displays the output from the program. Typically such programs are written in the scripting language PERL. The programs communicate with the server through channels defined by a Common Gateway Interface (CGI). That's why such systems are often referred to as CGI/PERL.

CGI programs allow web pages to be generated dynamically. For example, it would be easy to write a CGI program that displayed the current time (the time the script is run) in the web page it returns.

Here's a "Hello World" program for CGI/PERL. If you called it hello.cgi and put it on a webserver, then if you requested the file in your web browser, you'd get a hello world message.

#!/local/bin/perl
print "Content-type: text/html\n";
print "\n";
print ">HTML>\n";
print ">HEAD>\n";
print ">TITLE>A Test Page>/TITLE>\n";
print ">/HEAD>\n";
print ">BODY>\n";
print ">H1>A Test Page>/H1>\n";
print ">P>This is some text in the page.\n";
print ">/BODY>\n";
print ">/HTML>\n";
exit(0);

Note: The Content-type: line and the blank line that follow it are essential. The rest of the code just writes some HTML to standard output.

CGI/PERL Troubleshooting Checklist

On most webservers, all you basically have to do to set up a CGI/PERL script is to create a textfile containing the script (e.g. as above), FTP it to your webserver, and set read and execute access. There are, however, a few catches and you should refer to the following checklist if you can't get your CGI/PERL script to work.

Are the scripts protections set correctly? The PERL script file must be set with group and other execute permission.

Does the script have the right extension? Some webservers won't execute a script unless it has a file extension of .cgi. If in doubt, set the extension to this.

Is the script in the right place? Some webservers won't execute a script unless it is located within a directory called cgi-bin. If in doubt, create such a directory and move the script there. On some servers, only one particular cgi-bin directory is recognised.

Does the first line of the script point to PERL? The first line should point to the location of the PERL interpreter on your machine.

Does the script write out a content header? The first line generated by your script should be the content header (see the example above). The second line must be blank.

Are you generating bad HTML? If your script is generating bad HTML, then it might not be displayed even if the script has worked. If you think this might be happening, run the PERL script interactively on your local machine, and see what it produces.

Does your webserver have PERL? Most webservers do have PERL, but check this as a last resort.

My CGI/PERL Library

I have created a collection of PERL libraries which contain subroutines to perform all sorts of useful CGI/PERL operations. The libraries are available free of charge and can be found in the following FTP directory.

ftp://ftp.ross.net/lib_perl/

The directory contains at least the following libraries. This list might get out of date (i.e. it might omit recent additions to the library), so take a look in the FTP Directory too.

Assertions
Cookies
Countries
Dates and times
Email
Files
Forms
HTML
Miscellaneous
News
Paths
Protections
Random numbers
Records
Search
Semaphores
Site Maps
Strings
Tracing
Visitors

To use a libraries in CGI/PERL scripts, put the libraries you want to use (and any libraries those libraries use (see the requires commands at the top of each library) in a separate directory (e.g. called lib_perl in your web. Then at the top of each CGI/PERL script that uses the libraries, add the library directory to the PERL pathlist and then use the require command to pull in the libraries you want to use. Once you've done that, you can call subroutines within those libraries. For example:

     @INC = (@INC,"/web/data/clients/dave/lib_perl/");

     require ("lib_string.pl");
     require ("lib_html.pl");
     ...
     $x = $string_to_upper($x);
     &html_page("thepage.txt");

The libraries are provided "as is" for the convenience of those fmailiar with the basics of PERL and CGI scripting. Here are the notices that appear at the top of each library file:

# Copyright   : Copyright (C) Ross N. Williams 1997. All rights reserved.
#               However, permission is granted for anyone to use, modify,
#               and disseminate this package free of charge, so long as
#               these notices are retained, and all modifications are
#               logged in the History section below.
#
# No Warranty : There is no expressed or implied warranty on this software.
#               The software is provided "as is". Use at your own risk.
#
# Warning     : This library was created and tailored for the author's own
#               use and was released onto the Internet as an afterthought.
#               As such, the library may not be as "general" as it should
#               be, and may contains some undocumented hacks. If in doubt,
#               read the code to see what it's doing.

Here are some notes on using the libraries:

Assertion email: The assertion library sends you email if an assertion goes off. Please be sure to edit the assertion package so that it contains your email address. You need to do this even if you're not going to call the assertion library, as some of the other libraries call the assertion library. See the assertion library for more details.

HTTP headers: It's a good idea to defer the generation of the HTTP header until the very last minute. The reason for this is that the assertion package has to be able to display an error page at any time, so to be on the safe side, it outputs an HTTP header. If the HTTP header has already been written out, it will appear in the text of the output. Also, if you wish to output an error page using html_page or fool with cookies, you won't want the header to have been written out already.

Avoid too much text in CGI files: I've found it's a good idea to avoid large blocks of HTML in CGI/PERL files as it clutters up the script. Much better is to place the text in a file, and then write it out using html_page() or file_echo().

Use FunnelWeb: FunnelWeb is extremely useful when generating collections of CGI scripts for a web. For example, using FunnelWeb you can have a macro for the start and end of a CGI script, thus enabling you to set up a standard execution "environment" for each script in a web. If you're not using FunnelWeb, you're missing out on a lot. Check it out.



* * Webmaster: ross@ross.net
Linkhere: Click here to find out how to link here.
Copyright: Copyright © Ross N. Williams 1995-1996. All rights reserved.