CGI Programming on the World Wide Web

Previous Chapter 12
Debugging and Testing CGI Applications

12.5 CGI Lint--A Debugging/Testing Tool

CGI Lint greatly simplifies the process of testing and debugging CGI applications. Appendix E, Applications, Modules, Utilities, and Documentation, lists where you can get CGI Lint.

Depending on the type of request (either GET or POST), either one or two auxiliary files are required by CGI Lint. The first is a configuration file, which should contain a list of the environment variables in the following format:

QUERY_STRING       =   name=John Surge&company=ABC Corporation!
HTTP_ACCEPT        =   image/gif, image/x-xbitmap, image/jpeg, */*
REMOTE_ADDR        =
SERVER_ROOT        =   /usr/local/bin/httpd_1.4.2
DOCUMENT_ROOT      =   /usr/local/bin/httpd_1.4.2/public
SCRIPT_NAME        =   /cgi-bin/
REMOTE_HOST        =

This format has an advantage over the previous one: You do not need to encode the query string. However, if you have either %, &, or = characters in the query string, you need to escape them by placing a "\" before them:

QUERY_STRING       =   name=Joe\=Joseph&company=JP \& Play&percentage=50\%

Or you can just use the encoded values of %25, %26, and %3d to represent the "%," "&," and "=" characters, respectively. Now, you are ready to test out your CGI program:

% CGI_Lint get.cfg

CGI Lint executes the script that is pointed to by the environment variables SCRIPT_NAME and SERVER_ROOT. In addition, you can use a data file to store query information. Here is an example:

% CGI_Lint form.cfg

The format for the data file should be:

name = Joe\=Joseph
company = JP \& Play
percentage = 50\%

If you already have data stored in QUERY_STRING, CGI Lint will process the data from both sources. In the case of POST requests, all you have to do is change the REQUEST_METHOD to "POST" and run it in the same exact way as before:

% CGI_Lint form.cfg

In addition, you can test the multipart/form-data encoding scheme (see Appendix D, CGI Lite), which is a new addition to the Web. For multipart MIME data, you need to add the following line to the configuration file:

CONTENT_TYPE = multipart/form-data

Normally, multipart data contains boundary strings between fields, but you do not have to go to the trouble of inserting the numerous multipart headers. CGI Lint takes care of all that for you. Now, here is the format for the data file:

name = Joe = Joseph
company = JP & Play
percentage = 50%
review = */usr/shishir/rev.dat

You would execute the script in the same way as you did all the others. CGI Lint reads through the fields and creates a multipart MIME body:

Content-disposition: form-data; name="name"
Joe = Joseph
Content-disposition: form-data; name="company"
JP & Play
Content-disposition: form-data; name="percentage"
Content-disposition: form-data; name="review"; filename="/usr/ shishir/rev.dat"
(contents of the file /home/shishir/rev.dat)

One thing to note here is the last line of the data file. The asterisk instructs the tool to include the information stored in the file /usr/shishir/review.dat. That is one of the powerful features of multipart messages: it allows users to upload files to the server.

In addition to simulating the server data streams, CGI Lint also checks a number of attributes and properties before running the script.

CGI Lint in Action

Let's take a simple CGI program and run it through CGI Lint, and see what happens. Here is the program-it should be familiar to you, as it was introduced at the end of Chapter 7, Advanced Form Applications:

$user = $simple{'user'};
print "Content-type: text/plain", "\n\n";
print "Here are the results of your query: ", "\n";
print `/usr/ucb/finger $user`;
print "\n";
exit (0);

This program outputs finger information about the specified user. Here is the form that is associated with the program:

<INPUT TYPE="text" NAME="user" SIZE=40>
<INPUT TYPE="submit" VALUE="Get Information">

Now, let's create the configuration and data files, to be used with CGI Lint. The configuration file must contain the following lines:

SERVER_ROOT = /usr/local/bin/httpd_1.4.2
    SCRIPT_NAME = /cgi-bin/

Since the form passes the information to the program using POST, we need to create a data file to hold the post data. It needs to consist of only one line:

user = shishir

This is equivalent to the user entering "shishir" in the user field in the form. That is all that needs to be done. Here is how you would execute CGI Lint (assuming that the configuration file is called finger.cfg, and the data file is called finger.dat):

% CGI_Lint finger.cfg finger.dat

CGI Lint will output the following information:

While looking at your Perl script for possible security holes and
"open" commands, I came across the following statements that *might*
constitute a security breach:
Check the *backtics* on line: print `/usr/ucb/finger $user`;
Variable(s) *may* not be secure!

It looks as though your script has no bugs (at least, on the surface),
so here is the output you have been waiting for:
Here are the results of your query: <BR><HR>
Login name: shishir                     In real life: Shishir Gundavaram
Directory: /home/shishir                Shell: /usr/local/bin/tcsh
On since Oct 26 23:11:27 on ttyp0 from
Mail last read Mon Oct 27 00:03:54 1995
No Plan.

It will display the output generated by the CGI program. It also outputs various other information, including possible security holes. Here is a list of the exact informational messages that CGI Lint outputs:

Previous Home Next
Logging and Simulation Book Index Set UID/GID Wrapper

HTML: The Definitive Guide CGI Programming JavaScript: The Definitive Guide Programming Perl WebMaster in a Nutshell
Hosted by uCoz