Perl CGI + Apache + Windows

I have always thought it’s difficult to migrate Perl CGI script to Windows. I was wrong, and today I learned how to do it. The configuration part is actually 100% similar!

# This line will ensure only .cgi and .pl files are executed as CGI
AddHandler cgi-script .cgi .pl
Alias /request/ "C:/request/"
<directory "C:/request">
    AllowOverride None
    Options +ExecCGI
    Order allow,deny
    Allow from all

Now, all .cgi and .pl files are executed as CGI when run from the /request URI. You might have seen the ScriptAlias directive before – it processes everything in the specified directory as CGI. As an example:

ScriptAlias /request/ "C:/request/"
<directory "C:/request">
    AllowOverride None
    Options None
    Order allow,deny
    Allow from all

See the lack of the AddHandler directive? It’s no longer needed but it may be included if needed for other locations or directories. Now everything will be executed as a CGI. A CSS file in the directory will cause the server to return Error 500 (Internal Server Error).

One important thing when working with CGI is the shebang – the first line of the script that contains the full path to the interpreter. On Linux it looks like this:


While on Windows it will look like this:


This is the only problem with portability as you can’t have more than 1 shebang line!

Installing Perl is another part of the exercise. On Windows, the easiest way to get Perl is to install ActivePerl from ActiveState. If you’re migrating some code over to Windows, other than the Shebang you will need to install the required Perl modules. CPAN is available, but I suggest that you don’t use it unless very necessary. Since CPAN downloads the source code and tries to compile libraries, on a bare Windows system it’ll fail.

If you’re missing Perl modules you’ll see the error “Premature end of script” depending on how your Error 500 pages are configured. In Apache log, you’ll see:

[Fri Feb 13 10:00:21 2009] [error] [client 10.xx.yy.zz] Premature end of script headers: test.cgi
[Fri Feb 13 10:00:21 2009] [error] [client 10.xx.yy.zz] Can't locate DBD/ in @INC (@INC contains: C:/Perl/lib C:/Perl/site/lib .) at C:\request/ line 7.

That’s when we need to use ppm utility provided with ActivePerl:

> ppm help
Type 'help command' for more detailed help on a command.
    describe   - describes packages in detail
    exit       - exits the program
    help       - prints this screen, or help on 'command'
    install    - installs packages
    .... snip ....

Based on the error above, it’s time to install DBD::MySQL module.

ppm install DBD-mysql

I’m all set!

Since we’re already talking about Perl, if you need mod_perl you can use ppm to install:

ppm install

At the end of the installation it’ll ask for your Apache’s module directory and copy there.

The rest is easy:

LoadFile "C:/perl/bin/perl58.dll"
LoadModule perl_module modules/
Alias /mprequest "C:\mprequest"
<location /mprequest>
     SetHandler perl-script
     PerlResponseHandler ModPerl::Registry
     Options +ExecCGI
     PerlOptions +ParseHeaders

Of course, PerlResponseHandler should be set depending on what you need.

Have fun with Perl!