X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FEngine%2FFastCGI.pm;h=8e59958fd14bc29e1d35fa559c66650a77016dbd;hb=7fa2c9c1b85c98786655ad5169708d8dc84e8353;hp=ba182d39ad77c32ec45f9d6d138a0fd1d45c8231;hpb=5db46287d60238834e7488a6e856b51fc761f695;p=catagits%2FCatalyst-Runtime.git diff --git a/lib/Catalyst/Engine/FastCGI.pm b/lib/Catalyst/Engine/FastCGI.pm index ba182d3..8e59958 100644 --- a/lib/Catalyst/Engine/FastCGI.pm +++ b/lib/Catalyst/Engine/FastCGI.pm @@ -1,9 +1,10 @@ package Catalyst::Engine::FastCGI; -use strict; -use base 'Catalyst::Engine::CGI'; +use Moose; +extends 'Catalyst::Engine::CGI'; + eval "use FCGI"; -die "Please install FCGI\n" if $@; +die "Unable to load the FCGI module, you may need to install it:\n$@\n" if $@; =head1 NAME @@ -18,27 +19,57 @@ This is the FastCGI engine. This class overloads some methods from C. =head2 $self->run($c, $listen, { option => value, ... }) - + Starts the FastCGI server. If C<$listen> is set, then it specifies a location to listen for FastCGI requests; - Form Meaning - /path listen via Unix sockets on /path - :port listen via TCP on port on all interfaces - hostname:port listen via TCP on port bound to hostname +=over 4 + +=item /path + +listen via Unix sockets on /path + +=item :port + +listen via TCP on port on all interfaces + +=item hostname:port + +listen via TCP on port bound to hostname + +=back Options may also be specified; - Option Meaning - leave_umask Set to 1 to disable setting umask to 0 - for socket open - nointr Do not allow the listener to be - interrupted by Ctrl+C - nproc Specify a number of processes for - FCGI::ProcManager - pidfile Specify a filename for the pid file - manager Specify a FCGI::ProcManager sub-class - detach Detach from console +=over 4 + +=item leave_umask + +Set to 1 to disable setting umask to 0 for socket open =item nointr + +Do not allow the listener to be interrupted by Ctrl+C + +=item nproc + +Specify a number of processes for FCGI::ProcManager + +=item pidfile + +Specify a filename for the pid file + +=item manager + +Specify a FCGI::ProcManager sub-class + +=item detach + +Detach from console + +=item keep_stderr + +Send STDERR to STDOUT instead of the webserver + +=back =cut @@ -65,9 +96,12 @@ sub run { $options ||= {}; my %env; + my $error = \*STDERR; # send STDERR to the web server + $error = \*STDOUT # send STDERR to stdout (a logfile) + if $options->{keep_stderr}; # (if asked to) my $request = - FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%env, $sock, + FCGI::Request( \*STDIN, \*STDOUT, $error, \%env, $sock, ( $options->{nointr} ? 0 : &FCGI::FAIL_ACCEPT_ON_INTR ), ); @@ -101,7 +135,16 @@ sub run { while ( $request->Accept >= 0 ) { $proc_manager && $proc_manager->pm_pre_dispatch(); + + # If we're running under Lighttpd, swap PATH_INFO and SCRIPT_NAME + # http://lists.rawmode.org/pipermail/catalyst/2006-June/008361.html + # Thanks to Mark Blythe for this fix + if ( $env{SERVER_SOFTWARE} && $env{SERVER_SOFTWARE} =~ /lighttpd/ ) { + $env{PATH_INFO} ||= delete $env{SCRIPT_NAME}; + } + $class->handle_request( env => \%env ); + $proc_manager && $proc_manager->pm_post_dispatch(); } } @@ -118,6 +161,15 @@ sub write { $self->{_prepared_write} = 1; } + # XXX: We can't use Engine's write() method because syswrite + # appears to return bogus values instead of the number of bytes + # written: http://www.fastcgi.com/om_archive/mail-archive/0128.html + + # Prepend the headers if they have not yet been sent + if ( my $headers = delete $self->{_header_buf} ) { + $buffer = $headers . $buffer; + } + # FastCGI does not stream data properly if using 'print $handle', # but a syswrite appears to work properly. *STDOUT->syswrite($buffer); @@ -163,7 +215,7 @@ __END__ =head2 Standalone FastCGI Server -In server mode the application runs as a standalone server and accepts +In server mode the application runs as a standalone server and accepts connections from a web server. The application can be on the same machine as the web server, on a remote machine, or even on multiple remote machines. Advantages of this method include running the Catalyst application as a @@ -174,14 +226,14 @@ To start your application in server mode, install the FCGI::ProcManager module and then use the included fastcgi.pl script. $ script/myapp_fastcgi.pl -l /tmp/myapp.socket -n 5 - + Command line options for fastcgi.pl include: -d -daemon Daemonize the server. -p -pidfile Write a pidfile with the pid of the process manager. -l -listen Listen on a socket path, hostname:port, or :port. -n -nproc The number of processes started to handle requests. - + See below for the specific web server configurations for using the external server. @@ -190,25 +242,29 @@ server. Apache requires the mod_fastcgi module. The same module supports both Apache 1 and 2. -There are three ways to run your application under FastCGI on Apache: server, +There are three ways to run your application under FastCGI on Apache: server, static, and dynamic. =head3 Standalone server mode - FastCgiExternalServer /tmp/myapp -socket /tmp/myapp.socket - Alias /myapp/ /tmp/myapp/ - + FastCgiExternalServer /tmp/myapp.fcgi -socket /tmp/myapp.socket + Alias /myapp/ /tmp/myapp/myapp.fcgi/ + # Or, run at the root - Alias / /tmp/myapp/ - + Alias / /tmp/myapp.fcgi/ + # Optionally, rewrite the path when accessed without a trailing slash RewriteRule ^/myapp$ myapp/ [R] - -The FastCgiExternalServer directive tells Apache that when serving /tmp/myapp -to use the FastCGI application listenting on the socket /tmp/mapp.socket. -Note that /tmp/myapp does not need to exist -- it's a virtual file name. -It's likely that Apache is not configured to serve files in /tmp, so the + +The FastCgiExternalServer directive tells Apache that when serving +/tmp/myapp to use the FastCGI application listenting on the socket +/tmp/mapp.socket. Note that /tmp/myapp.fcgi does not need to exist -- +it's a virtual file name. With some versions of C or +C, you can use any name you like, but most require that the +virtual filename end in C<.fcgi>. + +It's likely that Apache is not configured to serve files in /tmp, so the Alias directive maps the url path /myapp/ to the (virtual) file that runs the FastCGI application. The trailing slashes are important as their use will correctly set the PATH_INFO environment variable used by Catalyst to @@ -226,14 +282,14 @@ FastCGI script to run your application. FastCgiServer /path/to/myapp/script/myapp_fastcgi.pl -processes 3 Alias /myapp/ /path/to/myapp/script/myapp_fastcgi.pl/ - + FastCgiServer tells Apache to start three processes of your application at startup. The Alias command maps a path to the FastCGI application. Again, the trailing slashes are important. - + =head3 Dynamic mode -In FastCGI dynamic mode, Apache will run your application on demand, +In FastCGI dynamic mode, Apache will run your application on demand, typically by requesting a file with a specific extension (e.g. .fcgi). ISPs often use this type of setup to provide FastCGI support to many customers. @@ -265,10 +321,20 @@ Here is a complete example: Then a request for /script/myapp_fastcgi.pl will run the application. - + For more information on using FastCGI under Apache, visit L +=head3 Authorization header with mod_fastcgi or mod_cgi + +By default, mod_fastcgi/mod_cgi do not pass along the Authorization header, +so modules like C will +not work. To enable pass-through of this header, add the following +mod_rewrite directives: + + RewriteCond %{HTTP:Authorization} ^(.+) + RewriteRule ^(.*)$ $1 [E=HTTP_AUTHORIZATION:%1,PT] + =head2 Lighttpd These configurations were tested with Lighttpd 1.4.7. @@ -289,7 +355,7 @@ These configurations were tested with Lighttpd 1.4.7. =head3 Static mode server.document-root = "/var/www/MyApp/root" - + fastcgi.server = ( "" => ( "MyApp" => ( @@ -302,12 +368,12 @@ These configurations were tested with Lighttpd 1.4.7. ) ) ) - + Note that in newer versions of lighttpd, the min-procs and idle-timeout values are disabled. The above example would start 5 processes. =head3 Non-root configuration - + You can also run your application at any non-root location with either of the above modes.