I doubt many of you have noticed that I am now running my blog software using FastCGI. I used the guides here and here to do it.
I modified the dispatch.fcgi code mentioned in the above links because I wanted to use mod_rewrite rules to call the dispatcher. This allowed the same dispatch.fcgi to respond to different requests. The code is at the end of the article.
To get this running, I installed dispatch.fcgi on my server such that it was located at /cgi-bin/mt/dispatch.fcgi. I then added the following lines to my Apache configuration, which allows me to direct any request for an fcgi script in my MT directory to the dispatcher.
RewriteRule ^/cgi-bin/mt/([^/]+\.fcgi)$ /cgi-bin/mt/dispatch.fcgi/$1 [QSA,L,PT]
<Location "/cgi-bin/mt">
AddHandler fcgid-script .fcgi
</Location>
I’m using mod_fcgid instead of mod_fastcgi to serve the scripts. I’m also working on moving my websites from Apache to lighttpd because of its better support for fastcgi. I’ll still run Apache as a backend to serve requests that lighttpd can’t handle.
#!/usr/bin/perl -w
use strict;
use lib $ENV{MT_HOME} ? "$ENV{MT_HOME}/lib" : 'lib';
use lib $ENV{MT_HOME} ? "$ENV{MT_HOME}/extlib" : 'extlib';
use MT::Bootstrap;
use CGI::Fast;
# preload app packages
use MT::App::CMS;
use MT::App::Comments;
use MT::App::Trackback;
use MT::App::Search;
## uncomment if necessary, but this adds a lot of
## overhead since it loads up LibXML.
use MT::AtomServer;
my $handlers = {
'mt.fcgi' => { class => 'MT::App::CMS', name => 'AdminScript' },
'mt-comments.fcgi' => { class => 'MT::App::Comments', name => 'CommentScript' },
'mt-tb.fcgi' => { class => 'MT::App::Trackback', name => 'TrackbackScript' },
'mt-search.fcgi' => { class => 'MT::App::Search', name => 'SearchScript' },
## See note above about this...
'mt-atom.fcgi' => { class => 'MT::AtomServer', name => 'AtomScript' },
};
eval {
while (my $q = new CGI::Fast) {
#my $cgi = $q->script_name;
my $cgi = $q->path_info;
$cgi =~ s!.*/!!;
my $pkg = $handlers->{$cgi}{class};
die "Invalid handler for $cgi" unless $pkg;
my $app = $pkg->new(CGIObject => $q) or die $pkg->errstr;
local $SIG{__WARN__} = sub { $app->trace($_[0]) };
$app->init_request(CGIObject => $q) unless $app->{init_request};
fixup_script_names($app);
$app->run;
my $mode = $app->mode || '';
if ("$pkg->$mode" eq 'MT::App::CMS->plugin_control') {
exit; # allows server to recycle after changing plugin switches
}
$app = undef;
$q = undef;
}
};
if ($@) {
print "Content-Type: text/html\n\n";
print "Got an error: $@";
}
sub fixup_script_names {
my ($app) = @_;
$app->config($handlers->{$_}{name}, $_) foreach keys %$handlers;
}


Update