[cgiapp] cgiapp, cap::Dispatch, fastcgi, and lighttpd -- a dummies guide.

George Hartzell hartzell at alerce.com
Sun Sep 7 13:51:20 EDT 2008


Last week I spent a little more time than I care to disclose getting
something that I wrote for CGI::Application::Dispatch::Server running
under lighttpd using fastcgi.  All of the necessary bits and hints are
scattered around and really anyone but a Dummy should be all set.
Since I managed to find a couple of sharp edges anyway, I thought it
might be worth gathering the info together here for posterity and/or
google.

I'm running everything from ports on FreeBSD-STABLE, but I don't think
that really matters for this.

* First things first.  When you enable debugging in your lighttpd.conf
  and find something like this: 

   2008-09-03 03:44:59: (mod_fastcgi.c.1033) child exited with
    status 9 /home/hartzell/oligodb/fcgi/oligodb.fcgi

  it probably means that whatever user lighttpd is running as is
  unable to read your instance script (oligodb.fcgi above), not that
  your instance script exited because of some problem it was having.
  I think that lighttpd should be able to get enough info from
  execvp/wait to tell the difference between being unable to start a
  child and having it start then exit, but I haven't had a chance to
  go bug hunting there yet.
  
* The next thing, you need to configure lighttpd to pass your requests
  to your instance script via fastcgi.  "Qiang at cgiapp from freenode"
  added a section to
  
    http://trac.lighttpd.net/trac/wiki/ApplicationsUsingLighttpd
  
  that contains most of the necessary info.  It helps to have the
  url.rewrite stanza so that you can use url's like
  "http://cgiapp/Home/home" and have them get passed via fastcgi to
  your instance script (which let them match the way that I'd been
  doing it under the standalone server).
  
  This setup puts the instance script into the htdocs directory.
  Other documentation for bin-path makes it clear that you can put the
  script anywhere.  If you *do* put it somewhere else, then you either
  have to put a dummy file in the right place in your htdocs directory
  or add
  
     "check-local" => "disable"
  
  in that same stanza.  If you don't do one or other other you'll get
  file not found errors, even though the file specified in bin-path is
  there (#$@@$!!!).  Not surprisingly, you should make sure that
  whatever you specify for "socket" is readable/writeable by whatever
  user lighttpd is running as.
  
* Next, you need to whip up a little instance script.  Qiang's wiki
  entry above gives the recipe for a standard CGI app and mentions
  that it's easy for CGI::Application::Dispatch too.  And it *is*
  easy, once you get past the 'exited with status 9' problem described
  above and the potential file-not-found problem.  The only trick is
  passing in a new CGI::Fast object for each query.  For the record,
  here's an instance script that works for me:
  
    #!/usr/bin/perl
  
    use warnings;
    use strict;
    #use lib qw(/usr/home/hartzell/oligodb/blib/lib);
    use CGI::Fast();
    use OligoDB::WebApp::Dispatch;
  
    while (my $q = new CGI::Fast) {
       OligoDB::WebApp::Dispatch->dispatch(args_to_new => {QUERY => $q});
    }
  
* You can also do it with FCGI::Dispatch.  Ron Savage posted a pointer
  to great demo app that pretty much works right out of the box (watch
  out for a couple of hard coded paths though), you can see his
  message at:
  
    http://www.mail-archive.com/cgiapp@lists.openlib.org/msg06532.html
  
  I naively thought that all of the necessary magic was included in
  his instance script, I transliterated it into my world and thought
  that things were working.  Actually, they only seemed to work but I
  had params from older queries popping up in later ones (not
  consistently, the bug depended on which of the pool of fastcgi
  processes the request was passed to.  It turns out that Ron was
  whipping up a fresh CGI::Simple object using cgiapp_get_query() in
  lib/CGI::Application/Test/Dispatch.pm.  Everything worked swimmingly
  with FCGI::Dispatch once I did something similar in my base class.
  
* For completeness' sake, Ron Savage also posted a description to the
  list of how to "do it" using FCGI::ProcManager.  I haven't tried it,
  but I'm betting it works....  You can read it at:
  
    http://www.mail-archive.com/cgiapp@lists.openlib.org/msg06730.html
  
 So in summary, write an script that uses either CGI::Fast or
 FCGI::Dispatch or FCGI::ProcManager that wraps your Dispatch class
 and make sure that someone's generating a new query object for each
 request, configure lighttp to pass those requests via fastcgi to the
 script (watch for permission problems and either put the instance
 script under the document root or set "check-local" appropriately),
 and away you go.

g.


More information about the cgiapp mailing list