views:

2350

answers:

4

I'm not of the Perl world, so some of this is new to me. I'm running Ubuntu Hardy LTS with apache2 and mod_fcgid packages installed. I'd like to get MT4 running under fcgid rather than mod-cgi (it seems to run OK with plain-old CGI).

I can't seem to get even a simple Perl script to run under fcgid. I created a simple "Hello World" app and included the code from this previous question to test if FCGI is running.

I named my script HelloWorld.fcgi (currently fcgid is set to handle .fcgi files only). Code:

#!/usr/bin/perl

use FCGI;

print "Content-type: text/html\n\n";
print "Hello world.\n\n";
my $request = FCGI::Request();
if ( $request->IsFastCGI ) { 
    print "we're running under FastCGI!\n";
} else { 
    print "plain old boring CGI\n";
}

When run from the command line, it prints "plain old boring..." When invoked via an http request to apache, I get a 500 Internal Server error and the output of the script is printed to the Apache error log:

Content-type: text/html

Hello world.

we're running under FastCGI!
[Wed Dec 03 22:26:19 2008] [warn] (104)Connection reset by peer: mod_fcgid: read data from fastcgi server error.
[Wed Dec 03 22:26:19 2008] [error] [client 70.23.221.171] Premature end of script headers: HelloWorld.fcgi
[Wed Dec 03 22:26:25 2008] [notice] mod_fcgid: process /www/mt/HelloWorld.fcgi(14189) exit(communication error), terminated by calling exit(), return code: 0

When I run the .cgi version of the same code, it works fine. Any idea why the output of the script is going to the error log? Apache config is the default mod_fcgid config plus, in a VirtualHost directive:

  ServerName test1.example.com
  DocumentRoot /www/example

  <Directory /www/example>
    AllowOverride None
    AddHandler cgi-script .cgi
    AddHandler fcgid-script .fcgi
    Options +ExecCGI +Includes +FollowSymLinks
  </Directory>
+2  A: 

I use CGI::Fast more than FCGI, but the idea is the same, I think. The goal of fast cgi is to load the program once, and iterate in a loop for every request.

FCGI's man page says :

use FCGI;

my $count = 0;
my $request = FCGI::Request();

while($request->Accept() >= 0) {
    print("Content-type: text/html\r\n\r\n", ++$count);
}

Which means, you have to Accept the request before being able to print anything back to the browser.

mat
Tried that, similar result. Also tried using a simple CGI::Fast Hello World -- also fails. So odd...
sstrudeau
+1  A: 

Movable Type uses CGI::Fast for FastCGI. The typical FastCGI script runs in a loop, as mat described. A loop that uses CGI::Fast would look like this:

#!/usr/bin/perl

use strict;
use CGI::Fast;

my $count = 0;
while (my $q = CGI::Fast->new) {
    print("Content-Type: text/plain\n\n");
    print("Process ID: $$; Count is: " . ++$count);
}

I tested this script on a server with the FCGI and CGI::Fast modules installed and count increments as you'd expect. If the process id changes, count will go back to 1 and then increment within that process. Each process has it's own variable space of course.

For MT, enabling FastCGI a matter of renaming (or symlinking) the cgi scripts to 'fcgi' (or making the handler for 'cgi' scripts fcgid, but that won't work for mt-xmlrpc.cgi which isn't FastCGI friendly yet). You'll also need to add some directives to your mt-config.cgi file so that it knows the new script names. Like this:

AdminScript mt.fcgi
CommentsScript mt-comments.fcgi

And so forth. More documentation specific to FastCGI and Movable Type is available on movabletype.org.

Brad Choate
+1  A: 

The problem is that the "Content-Type" header is sent outside of the request loop. You must print the "Content-Type" header for every request. If you move

print "Content-type: text/html\n\n";

to the top of the request loop it should fix the problem.

Also, you need to loop over the requests or you'll get no benefit, so following the first poster's example:

my $request = FCGI::Request();
while($request->Accept() >= 0) {
  print("Content-type: text/html\n\n");
}
Jamie
A: 

Anyway, based on your server's error logs, it looks like FCGI is working, and being invoked properly, but your script just isn't running in a loop, waiting for the next request to come along. So your test script did accomplish the task -- reporting whether FastCGI is configured or not. So now you should be able to reconfigure MT to use FastCGI.

Brad Choate