[Chapter 19] 19.9 Troubleshooting CGI Programs
Author: Randal Schwartz, Tom Christiansen & Larry Wall
Date: 1999-07-02T01:36:33Z

#

| Chapter 19 CGI Programming |

## 19.9 Troubleshooting CGI Programs

CGI programs launched from a web server run under a fundamentally different environment than they do when invoked from the command line. While you should always verify that your CGI program runs properly from the command line,[14] this isn't enough to guarantee that your program will work when called from the web server.

> [14] See the CGI.pm documentation for tips on command-line debugging.

You should get the CGI programming FAQ and a good book on CGI programming to help you in this. Some of these are listed at the end of this chapter. Here's a brief list of the frequent problems that arise in CGI programming. Almost all of them trigger those annoyingly unhelpful `500` `Server` `Error` messages that you will soon come to know and hate.

- If, when sending HTML to a browser, you forget the blank line between the HTTP header (that is, the `Content-type` line) and the body, it won't work. Remember to output a proper `Content-Type` line (and possibly other HTTP headers) plus a totally blank line before you do anything else.

- The server needs read and execute access to the script, so its permissions should usually be mode 0555 or, better, 0755. (This is UNIX-specific.)

- The directory where the script resides must itself be executable, so give it permissions of 0111 or, better, 0755. (This is UNIX-specific.)

- The script must be installed in the proper directory for your server configuration. For example, on some systems, it may be /usr/etc/httpd/cgi-bin/.

- You may need to have your script's filename end in a particular suffix, like .cgi or .pl. We advise against this setup, preferring to enable CGI execution on a per-directory basis instead, but some configurations may require it. Automatically assuming that anything ending in .cgi is executable is perilous if any directories are writable by FTP clients, or when mirroring someone else's directory structure. In both cases, executable programs may suddenly appear on your server without the webmaster's knowledge or consent. It also means that any files whose names end in .cgi or .pl can never again be fetched via a normal URL, an effect that ranges between undesirable and disastrous.

  Remember that the .pl suffix means it's a Perl library, not a Perl executable. Confusing these two will only make you unhappy in the long run. If you absolutely must have a unique suffix on a script to enable Perl execution (because your operating system just isn't clever enough to use something like the `#!/usr/bin/perl` notation), we suggest a suffix of .plx instead. But you still incur the other problems we just mentioned.

- Your server configuration requires CGI execution specially enabled for the directory you put your CGI script in. Make sure both GET and POST are allowed. (Your webmaster will know what that means.)

- The web server doesn't execute your script under your user ID. Make sure the files and directories accessed by the script are open to whatever user the web server runs scripts as, for example, `nobody`, `wwwuser`, or `httpd`. You may need to precreate such files and directories and give them wide-open write permissions. Under UNIX, this is done with `chmod` `a+w`. Always be alert to the risks when you grant such access to files.

- Always run your script under Perl's `-w` flag to get warnings. These go to the web-server error log, which contains any errors and warnings generated by your script. Learn the path to that logfile from your webmaster and check it for problems. See also the standard CGI::Carp module for how to handle errors better.

- Make sure that the versions and paths to Perl and any libraries you use (like CGI.pm) are what you're expecting them to be on the machine the web server is running on.

- Enable autoflush on the STDOUT filehandle at the top of your script by setting the `$|` variable to a true value, like 1. If you've the used the FileHandle module or any of the IO modules (like IO::File, IO::Socket, and so on), then you can use the more mnemonically named `autoflush()` method on the filehandle instead:

           use FileHandle;
           STDOUT->autoflush(1);

- Check the return value of every system call your program makes, and take appropriate action if the call fails.

19.8 Creating a Guestbook Program |  | 19.10 Perl and the Web: Beyond CGI Programming