Project

General

Profile

MasonRecipe » History » Revision 6

Revision 5 (Anonymous, 2006-09-21 14:12) → Revision 6/20 (Anonymous, 2007-02-02 19:39)

= Using Mason with lighttpd (via FastCGI) = 

 Mason can be used with Lighttpd and is (arguably :-) easier to setup that Apache + mod_perl. 

 Here's my current setup. Requirements: 

    * Mason handles files ending with '/' or '.html' or '.css'. 
    * Other files statically served by lighttpd 
    * Load perl modules at fastcgi process start 
    * Disallow access to .mhtml files 

 First we need a mason handler, that lighttpd will use via FastCGI. I've called it mason_lighttpd_handler.fcgi. It does not need to be in any particular location. 

 {{{ 
 #!/usr/bin/perl                                                                 

 use strict;                                                                     
 use HTML::Mason::CGIHandler;                                                    
 use CGI::Fast;                                                                  

 {                                                                               
   package HTML::Mason::Commands; 
  
   # anything you want available to components 
   # use DBI; 
   # use Other::Module; 
 } 

 # lazily-instantiated variables 
 my $cgi; 
 my $h; 

 $ENV{MASON_COMP_ROOT} = '/your/comp/root/goes/here'; 
 $ENV{MASON_DATA_ROOT} = '/your/data/root/goes/here''; 

 while ($cgi = new CGI::Fast) { 

   # this seems to be necessary as lighttpd does not provide the 
   # PATH_INFO and the QUERY_STRING environment variables 
   # Note that the below seems to work but I have no idea if it's the 
   # 'right' way to parse the REQUEST_URI out into PATH_INFO and QUERY_STRING 
   my $uri = $ENV{REQUEST_URI}; 
   if ($uri =~ /\?/) { 
     $uri =~ /^(.*?)\?(.*)/; 
     $ENV{PATH_INFO} = $1; 
     $ENV{QUERY_STRING} = $2; 
   } else { 
     $ENV{PATH_INFO} = $uri; 
     $ENV{QUERY_STRING} = ""; 
   } 
  
   # this is lazily instantiated because %ENV is not set at startup time 
   if (! $h) { 
     $h = HTML::Mason::CGIHandler->new(comp_root => $ENV{MASON_COMP_ROOT}, 
                                       data_dir => $ENV{MASON_DATA_ROOT}, 
                                       error_mode => 'fatal', 
                                       allow_globals => [qw($dbh $user $test)], 
                                       error_format => 'html'); 
   } 

   # hand off to mason 
   eval { $h->handle_cgi_object($cgi) }; 
   if (my $raw_error = $@) { 
     # print out a pretty system error page and log $raw_error 
     print $raw_error; 
   } 
 } 

 exit 0; 

 }}} 


 Next we need to tell Lighttpd to process requests for this site and process them via this script and FastCGI. Here is the relevant fragment. I'm using a regexp for the hostname expression 
 but you may need something less complicated - see the Lighttpd docs for more information: 

 {{{ 
 $HTTP["host"] =~ "hostnameexpression" { 
         server.document-root     = "/path/to/your/document/root" 

         fastcgi.map-extensions     = ( ".css" => ".html", "/" => ".html" )      # map .css and '/' to .html so they will be handled by FastCGI 
         index-file.names           = ( "index.html/" "index.html" ) 
         url.access-deny            = ( ".mhtml" ) 
         fastcgi.server             = ( ".html" => 
         ((  
              "socket"        => "/tmp/fastcgi.socket", 
              "bin-path"      => "/path/to/the/mason_lighttpd_handler.fcgi", 
              "check-local" => "disable" 
           )) 
         ) 
 } 
 }}} 

 That's it! 

 When you start lighttpd it will start several copies of your mason handler script, passing requests to them as appropriate.  

 One nice side-effect of this is that if you change a perl module (not a mason component) that would require you to restart/reload an apache mod_perl server, in this case you can just kill the perl fastcgi processes - lighttpd will notice and restart them, of course with your new module code in place. 

 Add debugging (via 'warn') to your handler script if you are getting unexpected results, you can see the output from it in the lighttpd eror log. 

 = Known issues = 

 $m->abort does not work correctly, see this page for details on why: 

 http://www.masonhq.com/docs/manual/1.28/CGIHandler.html#calling_abort___under_cgihandler 

 It looks like this is something that has to be fixed in Mason. 

 = Credits = 


 Let me know (Justin Hawkins <justin@hawkins.id.au>) if there are problems with this, particular with the REQUEST_URI parsing. This is very much in the category of "seems to work" at this stage.