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