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