I ran into a strange problem with a Perl CGI script yesterday. Upon script execution, I received the following error message from IIS:
CGI Error The specified CGI application misbehaved by not returning a complete set of HTTP headers.
A quick Google search of this error message turned up a number of discussions mentioning bugs in IIS, server configuration problems, etc. However, I suspected that my scripts were to blame (I had been hacking on them on Friday). But how could I determine whether I was at fault or if the server was to blame? Thankfully, the solution comes through one of the Perl CGI modules (here's the Perl tip):
use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
The Carp module (and where does that name come from?) gives us the
warningsToBrowser subroutines. When included in your script, any resulting Perl execution errors will be output into the browser window (very handy). After turning on these features, I immediately found my error. It resided in this line (here's the gotcha):
$safeProductName =~ s/\$/\\$/g;
It was my intent to replace any instances of the dollar sign character ($) with a backslash-dollar sign pair (\$). At first glance, this substitution rule may look alright. But it's not! The replacement portion of a substitution is treated as a double quoted string. So, the interpreter was escaping the backslash just fine, but then hits a naked dollar sign, indicating a variable (of which I didn't provide a name). And so it chokes! The line should have read:
$safeProductName =~ s/\$/\\\$/g;
Note the three backslashes in the replacement string. Two to print an actual backslash character, and one to print the actual dollar sign. Subtle? You bet.