At this point, you might be wondering where all
the CGI errors get logged. If you are using the NCSA
server, the log files directory is the place that holds them. You
can manually place debugging messages into the error_log
file by doing the following:
After the program is finished, you can look at the log file
to see the various debugging messages. It is a good practice to
insert the name of your program into the message, so you can find
it among all of the different messages logged to the file. Another
trick you can use is to "dupe" (or duplicate) standard error to
standard output:
print "Content-type: text/plain", "\n\n";
open (STDERR, ">&" . STDOUT);
print STDERR "About to execute for loop", "\n";
for ($loop=0; $loop <= 10; $loop++) {
$point[$loop] = ($loop * $center) + $random_number;
print STDERR "Point number ", $loop, " is ", $point[$loop], "\n";
}
close (STDERR);
In this case, the errors generated by the CGI program will
go to the browser as well as to the log file.
In order to get a good feel for how the
Web works, you should connect to a server and simulate a client's
actions. You can do this by using the
telnet protocol. Here is an example:
% telnet www.ora.com 80
Trying 198.112.208.13 ...
Connected to amber.ora.com.
Escape character is '^]'.
GET / HTTP/1.0
<HTML><HEAD>
<TITLE>oreilly.com Home Page</TITLE>
</HEAD><BODY>
<P><A HREF="https://bin.gnn.com/cgi-bin/imagemap/radio">
<IMG SRC="/gnn/bus/ora/radio.gif" ALT="" ISMAP></A>
.
.
.
</BODY></HTML>
Connection closed by foreign host.
You can enter other HTTP commands as well.
But remember that HTTP is a stateless protocol.
In other words, you can issue only one request, after which the
server terminates the connection. Now let's look at the issues behind
server simulation.
If you do not have access to a server
on a full-time basis, you can simulate the features of a server
quite easily. Before we look at how this can be accomplished, let's
look briefly at what the server actually does:
- Gets a request from the client to
serve a resource (either a file or a CGI program).
- Checks to see if the file is a CGI script.
- If it is, passes various environment variables/input
stream to the CGI program, and waits for output.
- Sends the output from either a regular file or CGI
to the client.
In
order to test CGI scripts, all we would have to do is emulate the
third step in this process. Let's look at a typical GET
request. First, we have to create a file to set the environment
variables (e.g., environment.vars). Here is
how you can do it in the C shell:
setenv REQUEST_METHOD 'GET'
setenv QUERY_STRING 'name=John%20Surge&company=ABC%20Corporation%21'
setenv HTTP_ACCEPT 'image/gif, image/x-xbitmap, image/jpeg, */*'
setenv SERVER_PROTOCOL 'HTTP/1.0'
setenv REMOTE_ADDR '198.198.198.198'
setenv DOCUMENT_ROOT '/usr/local/bin/httpd_1.4.2/public'
setenv GATEWAY_INTERFACE 'CGI/1.1'
setenv REQUEST_METHOD 'GET'
setenv SCRIPT_NAME '/cgi-bin/abc.pl'
setenv SERVER_SOFTWARE 'NCSA/1.4.2'
setenv REMOTE_HOST 'gateway.cgi.com'
In a Bourne-compatible
shell (such as Korn shell, bash, or zsh), the previous commands
will not work. Instead, you need the following syntax:
export REQUEST_METHOD = 'GET'
export QUERY_STRING = 'name=John%20Surge&company=ABC%20Corporation%21'
.
.
.
Then, we have to execute this script with the following command
(assuming the commands are stored in the file environment.vars)
in the C shell:
% source environment.vars
In a Bourne-compatible shell, you need to do the following:
Now,
you can simply run your CGI script, and it should work as though
it was being executed by the server. For POST
requests, the process is slightly different. You first have to create
a file that contains the POST information (e.g.,
post_data.txt):
name=John%20Surge&company=ABC%20Corporation%21&sports=Basketball&
exercise=3&runners=no
Once that is done, you need to determine the content length
(or the size in bytes) of the data. You can do that with the wc
command:
Then you need to add the following two lines to the environment
variable file that we created above (assuming C shell):
setenv REQUEST_METHOD 'POST'
setenv CONTENT_LENGTH '86'
Now all you have to do is send the data in the file to the
CGI program through a pipe:
% /usr/local/bin/httpd_1.4.2/cgi-bin/abc.pl < post_data.txt
That's all there is to it. The CGI Lint application automates
this procedure, as we will see next.