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
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: CGI or CGI::Fast
by Anonymous Monk on Sep 10, 2012 at 07:21 UTC | |
by afoken (Chancellor) on Sep 12, 2012 at 18:56 UTC |