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". ;-)

In reply to Re: CGI or CGI::Fast by afoken
in thread CGI or CGI::Fast by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.