Running CGI Scripts Under Catalyst
It is possible to run most CGI scripts under Catalyst using the modules Catalyst::Controller::WrapCGI and Catalyst::Controller::CGIBin.
Why would you want to do this?
Assuming you have a legacy CGI application, you may want to:
- integrate and package a CGI script into your Catalyst application, so you can (for example) use the Catalyst Authentication framework.
- have a Perl CGI script compiled on startup and cached, as with ModPerl::Registry, but in a FastCGI environment rather than with mod_perl under Apache.
port a simple mod_perl application to Catalyst.
An Example
Let's get the wwwboard application from the NMS project (http://nms-cgi.sourceforge.net/scripts.shtml) running under Catalyst.
We'll call the Catalyst application WWWBoard.
First, make a root/cgi-bin directory in your app, then copy the file
wwwboard.pl there.
Put the files wwwboard.html and faq.html into root/static.
Edit the configuration block in wwwboard.pl to:
$basedir = WWWBoard->path_to('root/static');
$baseurl = 'http://localhost:3000/';
$cgi_url = 'http://localhost:3000/cgi-bin/wwwboard.pl';
Next, make a Controller for running your CGIs:
package WWWBoard::Controller::Board;
use strict;
use warnings;
use parent 'Catalyst::Controller::CGIBin';
1;
Tell Static::Simple to not ignore .html files in WWWBoard.pm:
__PACKAGE__->config(
name => 'WWWBoard',
static => {
ignore_extensions => [ 'tt' ],
},
);
Rewire some URLs to the files the CGI will generate in Controller/Root.pm:
__PACKAGE__->config->{namespace} = '';
sub index : Path Args(0) {
my ($self, $c) = @_;
$c->serve_static_file($c->path_to('/root/static/wwwboard.html'));
}
sub board_html : Path('wwwboard.html') Args(0) {
my ($self, $c) = @_;
$c->serve_static_file($c->path_to('/root/static/wwwboard.html'));
}
sub faq_html : Path('faq.html') Args(0) {
my ($self, $c) = @_;
$c->serve_static_file($c->path_to('/root/static/faq.html'));
}
sub messages :Local Args {
my ($self, $c, @args) = @_;
$c->serve_static_file($c->path_to('/root/static/messages', @args));
}
Start the server, and you will be taken to a functional message board.
Even non-Perl CGIs will work, but of course these will not be pre-compiled.
Porting mod_perl Apps
The CGI environment is a bit closer to mod_perl than the regular Catalyst
Controller environment, e.g. you can print to STDOUT.
The first step would be to rewrite your handler sub to take $c
instead of $r as a parameter, and replace the Apache request methods
with the equivalent Catalyst framework methods.
Replacing things like Apache::Session with Catalyst::Plugin::Session is also fairly trivial.
Then your URL handler would look like:
use parent 'Catalyst::Controller::WrapCGI';
require My::ModPerl::Handler;
sub my_handler : Local {
my ($self, $c, @args) = @_;
$self->cgi_to_response($c, sub {
My::ModPerl::Handler::handler($c);
});
}
Other Examples
Justin Hunter (arcanez) has gotten the Movable Type blogging software running under Catalyst. It is available here: http://github.com/arcanez/mtcatalyst.
Hans Dieter Pearcey (confound) has gotten the Bugzilla bug-tracking project running under Catalyst. It is available here: http://opensourcery.com/blog/hans-dieter-pearcey/bugzilla-catalyst.
AUTHOR
Caelum: Rafael Kitover <rkitover@cpan.org>