http://www.perlmonks.org?node_id=992464

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

My only experience with perl CGI is with the module "CGI". I'm curious about CGI::Fast and was wondering if I should be using it instead of the normal CGI module.

Does anyone have any experience using CGI::Fast? Can you use it in a shared hosting environment, such as the ones offered at Pair?

What sort of changes to the code do I need to make if I switch to CGI::Fast, from CGI?

Thanks for reading and I look forward to your replies!

Replies are listed 'Best First'.
Re: CGI or CGI::Fast
by CountZero (Bishop) on Sep 08, 2012 at 11:27 UTC
    Does your server run Fast CGI? If not, there is no reason why you would use CGI::Fast.

    mod_fastcgi for Apache is a third-party module and can be found at www.fastcgi.com. You will also need to install the FCGI module from CPAN. Fast CGI also exists for other servers.

    Much more info is to be found in the documentation.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

    My blog: Imperial Deltronics

      I ran a small test on the server using "CGI::Fast qw(:standard);", the page was correctly displayed. So I assume that means FCGI is installed?

        Below FCGI lives the actual Fast CGI engine in your server. I do not know what FCGI does when there is no such engine in the server. Anything between degrading gracefully to the "normal" CGI protocol and crashing loudly is possible.

        Ask your sysadmin if he has mod_fastcgi (when your server is Apache) active in your (virtual) server.

        CountZero

        A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

        My blog: Imperial Deltronics
Re: CGI or CGI::Fast
by afoken (Chancellor) on Sep 10, 2012 at 06:36 UTC

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

      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". ;-)
Re: CGI or CGI::Fast
by sundialsvc4 (Abbot) on Sep 10, 2012 at 04:05 UTC

    Many hosting services do offer FastCGI, and there are several ways that (e.g.) the Apache server can offer it, one of which appears to be distinctly tilted toward the needs of hosting companies.   The only way to know which options can be made available to you is, of course, to ask them directly.

    I like to design web servers to use Plack, which gives the ability to choose which deployment strategy works best for you, and to change that strategy with little or no impact to your code.   Plack “abstracts away” such differences and does an excellent job of it.

      I came across Plack while googling for FCGI, but have yet to read more about it. I've code that runs on Perl's CGI, and I naively thought that I could switch to CGI::Fast by just installing the module and FCGI - since both are listed as installed on the shared server. Apparently, however, it's not just these two modules but also the fastcgi engine, which is not available.

        Plack is, of course, an interface layer ... it provides a simple, consistent interface for you to write to, and then a set of personality-modules which you select according to the environment.   (One of those is, “ordinary CGI.”)   If your hosting service does not and cannot provide FastCGI, and the omission is business-important for you, just move to a different provider and change where your DNS entry goes. . .

        But remember that it might not actually matter.   Most operating systems are “lazy” about getting rid of recently-used code segments, in anticipation that the same programs are often used repeatedly.   (The notion of “locality of reference” also has a corollary with regard to which programs are being requested.)