authors cleanup
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Engine / FastCGI.pm
1 package Catalyst::Engine::FastCGI;
2
3 use strict;
4 use base 'Catalyst::Engine::CGI';
5 eval "use FCGI";
6 die "Unable to load the FCGI module, you may need to install it:\n$@\n" if $@;
7
8 =head1 NAME
9
10 Catalyst::Engine::FastCGI - FastCGI Engine
11
12 =head1 DESCRIPTION
13
14 This is the FastCGI engine.
15
16 =head1 OVERLOADED METHODS
17
18 This class overloads some methods from C<Catalyst::Engine::CGI>.
19
20 =head2 $self->run($c, $listen, { option => value, ... })
21  
22 Starts the FastCGI server.  If C<$listen> is set, then it specifies a
23 location to listen for FastCGI requests;
24
25 =over 4
26
27 =item /path
28
29 listen via Unix sockets on /path
30
31 =item :port
32
33 listen via TCP on port on all interfaces
34
35 =item hostname:port
36
37 listen via TCP on port bound to hostname
38
39 =back
40
41 Options may also be specified;
42
43 =over 4
44
45 =item leave_umask
46
47 Set to 1 to disable setting umask to 0 for socket open =item nointr
48
49 Do not allow the listener to be interrupted by Ctrl+C
50
51 =item nproc
52
53 Specify a number of processes for FCGI::ProcManager
54
55 =item pidfile
56
57 Specify a filename for the pid file
58
59 =item manager
60
61 Specify a FCGI::ProcManager sub-class
62
63 =item detach          
64
65 Detach from console
66
67 =item keep_stderr
68
69 Send STDERR to STDOUT instead of the webserver
70
71 =back
72
73 =cut
74
75 sub run {
76     my ( $self, $class, $listen, $options ) = @_;
77
78     my $sock = 0;
79     if ($listen) {
80         my $old_umask = umask;
81         unless ( $options->{leave_umask} ) {
82             umask(0);
83         }
84         $sock = FCGI::OpenSocket( $listen, 100 )
85           or die "failed to open FastCGI socket; $!";
86         unless ( $options->{leave_umask} ) {
87             umask($old_umask);
88         }
89     }
90     elsif ( $^O ne 'MSWin32' ) {
91         -S STDIN
92           or die "STDIN is not a socket; specify a listen location";
93     }
94
95     $options ||= {};
96
97     my %env;
98     my $error = \*STDERR; # send STDERR to the web server
99        $error = \*STDOUT  # send STDERR to stdout (a logfile)
100          if $options->{keep_stderr}; # (if asked to)
101     
102     my $request =
103       FCGI::Request( \*STDIN, \*STDOUT, $error, \%env, $sock,
104         ( $options->{nointr} ? 0 : &FCGI::FAIL_ACCEPT_ON_INTR ),
105       );
106
107     my $proc_manager;
108
109     if ($listen) {
110         $options->{manager} ||= "FCGI::ProcManager";
111         $options->{nproc}   ||= 1;
112
113         $self->daemon_fork() if $options->{detach};
114
115         if ( $options->{manager} ) {
116             eval "use $options->{manager}; 1" or die $@;
117
118             $proc_manager = $options->{manager}->new(
119                 {
120                     n_processes => $options->{nproc},
121                     pid_fname   => $options->{pidfile},
122                 }
123             );
124
125             # detach *before* the ProcManager inits
126             $self->daemon_detach() if $options->{detach};
127
128             $proc_manager->pm_manage();
129         }
130         elsif ( $options->{detach} ) {
131             $self->daemon_detach();
132         }
133     }
134
135     while ( $request->Accept >= 0 ) {
136         $proc_manager && $proc_manager->pm_pre_dispatch();
137         
138         # If we're running under Lighttpd, swap PATH_INFO and SCRIPT_NAME
139         # http://lists.rawmode.org/pipermail/catalyst/2006-June/008361.html
140         # Thanks to Mark Blythe for this fix
141         if ( $env{SERVER_SOFTWARE} && $env{SERVER_SOFTWARE} =~ /lighttpd/ ) {
142             $env{PATH_INFO} ||= delete $env{SCRIPT_NAME};
143         }
144         
145         $class->handle_request( env => \%env );
146         
147         $proc_manager && $proc_manager->pm_post_dispatch();
148     }
149 }
150
151 =head2 $self->write($c, $buffer)
152
153 =cut
154
155 sub write {
156     my ( $self, $c, $buffer ) = @_;
157
158     unless ( $self->{_prepared_write} ) {
159         $self->prepare_write($c);
160         $self->{_prepared_write} = 1;
161     }
162     
163     # XXX: We can't use Engine's write() method because syswrite
164     # appears to return bogus values instead of the number of bytes
165     # written: http://www.fastcgi.com/om_archive/mail-archive/0128.html
166     
167     # Prepend the headers if they have not yet been sent
168     if ( my $headers = delete $self->{_header_buf} ) {
169         $buffer = $headers . $buffer;
170     }
171
172     # FastCGI does not stream data properly if using 'print $handle',
173     # but a syswrite appears to work properly.
174     *STDOUT->syswrite($buffer);
175 }
176
177 =head2 $self->daemon_fork()
178
179 Performs the first part of daemon initialisation.  Specifically,
180 forking.  STDERR, etc are still connected to a terminal.
181
182 =cut
183
184 sub daemon_fork {
185     require POSIX;
186     fork && exit;
187 }
188
189 =head2 $self->daemon_detach( )
190
191 Performs the second part of daemon initialisation.  Specifically,
192 disassociates from the terminal.
193
194 However, this does B<not> change the current working directory to "/",
195 as normal daemons do.  It also does not close all open file
196 descriptors (except STDIN, STDOUT and STDERR, which are re-opened from
197 F</dev/null>).
198
199 =cut
200
201 sub daemon_detach {
202     my $self = shift;
203     print "FastCGI daemon started (pid $$)\n";
204     open STDIN,  "+</dev/null" or die $!;
205     open STDOUT, ">&STDIN"     or die $!;
206     open STDERR, ">&STDIN"     or die $!;
207     POSIX::setsid();
208 }
209
210 1;
211 __END__
212
213 =head1 WEB SERVER CONFIGURATIONS
214
215 =head2 Standalone FastCGI Server
216
217 In server mode the application runs as a standalone server and accepts 
218 connections from a web server.  The application can be on the same machine as
219 the web server, on a remote machine, or even on multiple remote machines.
220 Advantages of this method include running the Catalyst application as a
221 different user than the web server, and the ability to set up a scalable
222 server farm.
223
224 To start your application in server mode, install the FCGI::ProcManager
225 module and then use the included fastcgi.pl script.
226
227     $ script/myapp_fastcgi.pl -l /tmp/myapp.socket -n 5
228     
229 Command line options for fastcgi.pl include:
230
231     -d -daemon     Daemonize the server.
232     -p -pidfile    Write a pidfile with the pid of the process manager.
233     -l -listen     Listen on a socket path, hostname:port, or :port.
234     -n -nproc      The number of processes started to handle requests.
235     
236 See below for the specific web server configurations for using the external
237 server.
238
239 =head2 Apache 1.x, 2.x
240
241 Apache requires the mod_fastcgi module.  The same module supports both
242 Apache 1 and 2.
243
244 There are three ways to run your application under FastCGI on Apache: server, 
245 static, and dynamic.
246
247 =head3 Standalone server mode
248
249     FastCgiExternalServer /tmp/myapp.fcgi -socket /tmp/myapp.socket
250     Alias /myapp/ /tmp/myapp/myapp.fcgi/
251     
252     # Or, run at the root
253     Alias / /tmp/myapp.fcgi/
254     
255     # Optionally, rewrite the path when accessed without a trailing slash
256     RewriteRule ^/myapp$ myapp/ [R]
257     
258
259 The FastCgiExternalServer directive tells Apache that when serving
260 /tmp/myapp to use the FastCGI application listenting on the socket
261 /tmp/mapp.socket.  Note that /tmp/myapp.fcgi does not need to exist --
262 it's a virtual file name.  With some versions of C<mod_fastcgi> or
263 C<mod_fcgid>, you can use any name you like, but most require that the
264 virtual filename end in C<.fcgi>.
265
266 It's likely that Apache is not configured to serve files in /tmp, so the 
267 Alias directive maps the url path /myapp/ to the (virtual) file that runs the
268 FastCGI application. The trailing slashes are important as their use will
269 correctly set the PATH_INFO environment variable used by Catalyst to
270 determine the request path.  If you would like to be able to access your app
271 without a trailing slash (http://server/myapp), you can use the above
272 RewriteRule directive.
273
274 =head3 Static mode
275
276 The term 'static' is misleading, but in static mode Apache uses its own
277 FastCGI Process Manager to start the application processes.  This happens at
278 Apache startup time.  In this case you do not run your application's
279 fastcgi.pl script -- that is done by Apache. Apache then maps URIs to the
280 FastCGI script to run your application.
281
282     FastCgiServer /path/to/myapp/script/myapp_fastcgi.pl -processes 3
283     Alias /myapp/ /path/to/myapp/script/myapp_fastcgi.pl/
284     
285 FastCgiServer tells Apache to start three processes of your application at
286 startup.  The Alias command maps a path to the FastCGI application. Again,
287 the trailing slashes are important.
288     
289 =head3 Dynamic mode
290
291 In FastCGI dynamic mode, Apache will run your application on demand, 
292 typically by requesting a file with a specific extension (e.g. .fcgi).  ISPs
293 often use this type of setup to provide FastCGI support to many customers.
294
295 In this mode it is often enough to place or link your *_fastcgi.pl script in
296 your cgi-bin directory with the extension of .fcgi.  In dynamic mode Apache
297 must be able to run your application as a CGI script so ExecCGI must be
298 enabled for the directory.
299
300     AddHandler fastcgi-script .fcgi
301
302 The above tells Apache to run any .fcgi file as a FastCGI application.
303
304 Here is a complete example:
305
306     <VirtualHost *:80>
307         ServerName www.myapp.com
308         DocumentRoot /path/to/MyApp
309
310         # Allow CGI script to run
311         <Directory /path/to/MyApp>
312             Options +ExecCGI
313         </Directory>
314
315         # Tell Apache this is a FastCGI application
316         <Files myapp_fastcgi.pl>
317             SetHandler fastcgi-script
318         </Files>
319     </VirtualHost>
320
321 Then a request for /script/myapp_fastcgi.pl will run the
322 application.
323     
324 For more information on using FastCGI under Apache, visit
325 L<http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html>
326
327 =head3 Authorization header with mod_fastcgi or mod_cgi
328
329 By default, mod_fastcgi/mod_cgi do not pass along the Authorization header,
330 so modules like C<Catalyst::Plugin::Authentication::Credential::HTTP> will
331 not work.  To enable pass-through of this header, add the following
332 mod_rewrite directives:
333
334     RewriteCond %{HTTP:Authorization} ^(.+)
335     RewriteRule ^(.*)$ $1 [E=HTTP_AUTHORIZATION:%1,PT]
336
337 =head2 Lighttpd
338
339 These configurations were tested with Lighttpd 1.4.7.
340
341 =head3 Standalone server mode
342
343     server.document-root = "/var/www/MyApp/root"
344
345     fastcgi.server = (
346         "" => (
347             "MyApp" => (
348                 "socket"      => "/tmp/myapp.socket",
349                 "check-local" => "disable"
350             )
351         )
352     )
353
354 =head3 Static mode
355
356     server.document-root = "/var/www/MyApp/root"
357     
358     fastcgi.server = (
359         "" => (
360             "MyApp" => (
361                 "socket"       => "/tmp/myapp.socket",
362                 "check-local"  => "disable",
363                 "bin-path"     => "/var/www/MyApp/script/myapp_fastcgi.pl",
364                 "min-procs"    => 2,
365                 "max-procs"    => 5,
366                 "idle-timeout" => 20
367             )
368         )
369     )
370     
371 Note that in newer versions of lighttpd, the min-procs and idle-timeout
372 values are disabled.  The above example would start 5 processes.
373
374 =head3 Non-root configuration
375     
376 You can also run your application at any non-root location with either of the
377 above modes.  Note the required mod_rewrite rule.
378
379     url.rewrite = ( "myapp\$" => "myapp/" )
380     fastcgi.server = (
381         "/myapp" => (
382             "MyApp" => (
383                 # same as above
384             )
385         )
386     )
387
388 For more information on using FastCGI under Lighttpd, visit
389 L<http://www.lighttpd.net/documentation/fastcgi.html>
390
391 =head2 IIS
392
393 It is possible to run Catalyst under IIS with FastCGI, but we do not
394 yet have detailed instructions.
395
396 =head1 SEE ALSO
397
398 L<Catalyst>, L<FCGI>.
399
400 =head1 AUTHORS
401
402 Catalyst Contributors, see Catalyst.pm
403
404 =head1 THANKS
405
406 Bill Moseley, for documentation updates and testing.
407
408 =head1 COPYRIGHT
409
410 This program is free software, you can redistribute it and/or modify it under
411 the same terms as Perl itself.
412
413 =cut