Recipe 21.12 Migrating from CGI to mod_perl

21.12.1 Problem

Your CGI script is called so often that your web server's performance deteriorates unacceptably. You'd like to use mod_perl to make things faster.

21.12.2 Solution

Use Apache::Registry or Apache::PerlRun:

PerlModule Apache::Registry
# or Apache::PerlRun
PerlModule CGI
PerlSendHeader On

Alias /perl/ /real/path/to/perl/scripts/
<Location /perl>
SetHandler  perl-script
PerlHandler Apache::Registry
# or Apache::PerlRun
Options ExecCGI

21.12.3 Discussion

The Solution tells Apache that requests with URLs starting in /perl/ are in /real/path/to/perl/scripts/ and that Apache::Registry handles them. This module runs them in a CGI environment. PerlModule CGI preloads the CGI module, and PerlSendHeader On makes most CGI scripts work out of the box with mod_perl.

We have configured /perl/ to work analogously to /cgi-bin/. To make the suffix .perl indicate mod_perl CGI scripts, just as the suffix .cgi indicates regular CGI scripts, use the following in your Apache configuration file:

<Files *.perl>
SetHandler  perl-script
PerlHandler Apache::Registry
Options ExecCGI

Because the Perl interpreter that runs your CGI script doesn't shut down when your script is done, as would occur when the web server runs your script as a separate program, you cannot rely on global variables being undefined when the script runs repeatedly. The warnings and strict pragmas check for many bad habits in these kinds of scripts. There are other gotchas, toosee the mod_perl_traps manpage.

The Apache::PerlRun handler can work around some of these traps. This is like Apache::Registry, but doesn't cache the compiled module. If your CGI program is sloppy and doesn't initialize variables or close filehandles, you can still gain speed by not starting a new process for every request. To use it, substitute Apache::PerlRun for Apache::Registry.

Your scripts aren't preloaded, so each web server process carries its own copy around. To share the code between processes, load them during Apache configuration with either the Apache::RegistryLoader module, PerlModule sections of httpd.conf, or a file.

21.12.4 See Also

The manpage; the documentation for Bundle::Apache, Apache, Apache::Registry, Apache::RegistryLoader, and Apache::PerlRun from CPAN;; the mod_perl FAQ at; the mod_perl(3) and cgi_to_mod_perl(1) manpages (if you have them); Recipes 2.1 through 2.5 in mod_perl Developer's Cookbook