in reply to CGI or CGI::Fast

First, a litte bit of theory:

CGI and FastCGI are two very different, but related interfaces between webserver and application. The main difference is that CGI starts another instance of the application for each HTTP request, whereas FastCGI keeps the application running and just sends messages to the application over a socket. This way, FastCGI avoids the creation of a new process and the slow startup of the application, and that's all that makes FastCGI faster than classic CGI. The price you have to pay is that you have to be much more careful about global variables, because global variables are no longer per HTTP request, but they are shared for lots of requests, for different users with different privileges.

Now for some code:

CGI::Fast uses FCGI internally. FCGI can tell the difference between being called as CGI application and being called as FastCGI application. In both cases, it offers the same interface, pretending to be a stupid "single shot" FastCGI application when it was invoked via CGI.

To find out how your application was invoked, you "just" have to call FCGI's IsFastCGI() method on the FastCGI handle stored inside CGI::Fast. Luckily, CGI::Fast stores that handle in a package global variable called $Ext_Request. The following code should work:

#!/usr/bin/perl use strict; use warnings; use CGI::Fast qw(:standard); sub mode { my $h=$CGI::Fast::Ext_Request; if (defined($h) && ref($h) && $h->IsFastCGI()) { return 'FastCGI'; } else { return 'CGI'; } } while (CGI::Fast->new()) { print header(), start_html('CGI or FastCGI?'), h1('CGI or FastCGI?'), p('This application runs in ',mode(),' mode.'), end_html(); }

Unfortunately, older CGI::Fast versions (1.08 and possibly older) do not initialise $Ext_Request in all cases. (CGI::Fast was changed with CGI 3.56, released 2011-Nov-08.) Common web hosters rarely update Perl and Perl modules, so it is very likely that you have to work with old or ancient versions of Perl, CGI, CGI::Fast and FCGI.

So, to be sure, you need to bypass CGI::Fast, like this:

#!/usr/bin/perl use strict; use warnings; use FCGI; my $r=FCGI::Request(); while ($r->Accept()>=0) { print "Content-Type: text/html\r\n", "\r\n", "<!DOCTYPE html>", "<html><head><meta charset=\"us-ascii\"><title>CGI or +FastCGI?</title></head>\n", "<body><h1>CGI or FastCGI?</h1>\n", '<p>This application runs in ',($r->IsFastCGI() ? 'Fas +tCGI' : 'CGI')," mode.</p>\n", "</body></html>\n"; }

If that fails to run, your copy of FCGI is really, really old, and you should possibly avoid it.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

Replies are listed 'Best First'.
Re^2: CGI or CGI::Fast
by Anonymous Monk on Sep 10, 2012 at 07:21 UTC

    Many thanks, Alexander!

    I was a bit surprised there wasn't a simple way to test and I'm thankful for your code. I ran your code on my local server and on the server at the hosting end (I have an existing plan). The good thing is the code works like a champ but the bad thing is that both the local and production servers don't support CGI::Fast :(

    Well, at least now I can put that thought of using CGI::Fast aside and be content with just CGI :)

      Running programs as FastCGI instead of CGI typically requires some webserver configuration. The mod_fastcgi plugin for Apache offers different options:

      • Have a custom program file extension, like .fcgi or .fpl. This is configured via AddHandler.
      • Have a special location reserved for FastCGI programs (comparable to the typical /cgi-bin/ location). This is configured via SetHandler.
      • Have a special location (URL prefix) reserved for a single FastCGI program under control of the Apache server. This is configured via FastCGIServer.
      • Have a special location (URL prefix) reserved for a single FastCGI program controlled by some other program (init, daemontools, ...). This is configured via FastCGIExternalServer.

      When you place a FastCGI capable CGI program in /cgi-bin/ (or any other location configured for CGI scripts), it will run in CGI mode, not in FastCGI mode. The same happens when the program name ends with .cgi (or any other extension mapped to plain CGI).

      So, perhaps renaming or moving your program may be sufficient. Ask the webserver administrator / hoster support.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)