tabs => spaces
[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 }
4f5ebacd 162
fbcc39ad 163 # FastCGI does not stream data properly if using 'print $handle',
164 # but a syswrite appears to work properly.
4f5ebacd 165 *STDOUT->syswrite($buffer);
e2fd5b5f 166}
167
b5ecfcf0 168=head2 $self->daemon_fork()
526b698a 169
170Performs the first part of daemon initialisation. Specifically,
171forking. STDERR, etc are still connected to a terminal.
172
173=cut
174
175sub daemon_fork {
176 require POSIX;
177 fork && exit;
178}
179
b5ecfcf0 180=head2 $self->daemon_detach( )
526b698a 181
182Performs the second part of daemon initialisation. Specifically,
183disassociates from the terminal.
184
185However, this does B<not> change the current working directory to "/",
186as normal daemons do. It also does not close all open file
187descriptors (except STDIN, STDOUT and STDERR, which are re-opened from
188F</dev/null>).
189
190=cut
191
192sub daemon_detach {
193 my $self = shift;
194 print "FastCGI daemon started (pid $$)\n";
b5ecfcf0 195 open STDIN, "+</dev/null" or die $!;
196 open STDOUT, ">&STDIN" or die $!;
197 open STDERR, ">&STDIN" or die $!;
526b698a 198 POSIX::setsid();
199}
200
198b0efa 2011;
202__END__
203
198b0efa 204=head1 WEB SERVER CONFIGURATIONS
205
d7d72ad9 206=head2 Standalone FastCGI Server
207
208In server mode the application runs as a standalone server and accepts
209connections from a web server. The application can be on the same machine as
210the web server, on a remote machine, or even on multiple remote machines.
211Advantages of this method include running the Catalyst application as a
212different user than the web server, and the ability to set up a scalable
213server farm.
198b0efa 214
d7d72ad9 215To start your application in server mode, install the FCGI::ProcManager
216module and then use the included fastcgi.pl script.
198b0efa 217
d7d72ad9 218 $ script/myapp_fastcgi.pl -l /tmp/myapp.socket -n 5
198b0efa 219
d7d72ad9 220Command line options for fastcgi.pl include:
221
222 -d -daemon Daemonize the server.
223 -p -pidfile Write a pidfile with the pid of the process manager.
224 -l -listen Listen on a socket path, hostname:port, or :port.
225 -n -nproc The number of processes started to handle requests.
198b0efa 226
d7d72ad9 227See below for the specific web server configurations for using the external
228server.
198b0efa 229
d7d72ad9 230=head2 Apache 1.x, 2.x
231
232Apache requires the mod_fastcgi module. The same module supports both
233Apache 1 and 2.
234
235There are three ways to run your application under FastCGI on Apache: server,
236static, and dynamic.
237
238=head3 Standalone server mode
239
3f0911d3 240 FastCgiExternalServer /tmp/myapp.fcgi -socket /tmp/myapp.socket
241 Alias /myapp/ /tmp/myapp/myapp.fcgi/
d7d72ad9 242
243 # Or, run at the root
3f0911d3 244 Alias / /tmp/myapp.fcgi/
d7d72ad9 245
246 # Optionally, rewrite the path when accessed without a trailing slash
247 RewriteRule ^/myapp$ myapp/ [R]
248
3f0911d3 249
250The FastCgiExternalServer directive tells Apache that when serving
251/tmp/myapp to use the FastCGI application listenting on the socket
252/tmp/mapp.socket. Note that /tmp/myapp.fcgi does not need to exist --
253it's a virtual file name. With some versions of C<mod_fastcgi> or
254C<mod_fcgid>, you can use any name you like, but most require that the
255virtual filename end in C<.fcgi>.
d7d72ad9 256
257It's likely that Apache is not configured to serve files in /tmp, so the
258Alias directive maps the url path /myapp/ to the (virtual) file that runs the
259FastCGI application. The trailing slashes are important as their use will
260correctly set the PATH_INFO environment variable used by Catalyst to
261determine the request path. If you would like to be able to access your app
262without a trailing slash (http://server/myapp), you can use the above
263RewriteRule directive.
264
265=head3 Static mode
266
267The term 'static' is misleading, but in static mode Apache uses its own
268FastCGI Process Manager to start the application processes. This happens at
269Apache startup time. In this case you do not run your application's
270fastcgi.pl script -- that is done by Apache. Apache then maps URIs to the
271FastCGI script to run your application.
272
273 FastCgiServer /path/to/myapp/script/myapp_fastcgi.pl -processes 3
274 Alias /myapp/ /path/to/myapp/script/myapp_fastcgi.pl/
198b0efa 275
d7d72ad9 276FastCgiServer tells Apache to start three processes of your application at
277startup. The Alias command maps a path to the FastCGI application. Again,
278the trailing slashes are important.
198b0efa 279
d7d72ad9 280=head3 Dynamic mode
281
282In FastCGI dynamic mode, Apache will run your application on demand,
283typically by requesting a file with a specific extension (e.g. .fcgi). ISPs
284often use this type of setup to provide FastCGI support to many customers.
285
286In this mode it is often enough to place or link your *_fastcgi.pl script in
287your cgi-bin directory with the extension of .fcgi. In dynamic mode Apache
288must be able to run your application as a CGI script so ExecCGI must be
289enabled for the directory.
290
291 AddHandler fastcgi-script .fcgi
292
293The above tells Apache to run any .fcgi file as a FastCGI application.
294
295Here is a complete example:
296
297 <VirtualHost *:80>
298 ServerName www.myapp.com
299 DocumentRoot /path/to/MyApp
300
301 # Allow CGI script to run
302 <Directory /path/to/MyApp>
303 Options +ExecCGI
304 </Directory>
305
306 # Tell Apache this is a FastCGI application
307 <Files myapp_fastcgi.pl>
308 SetHandler fastcgi-script
309 </Files>
198b0efa 310 </VirtualHost>
d7d72ad9 311
312Then a request for /script/myapp_fastcgi.pl will run the
313application.
198b0efa 314
315For more information on using FastCGI under Apache, visit
316L<http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html>
317
318=head2 Lighttpd
319
d7d72ad9 320These configurations were tested with Lighttpd 1.4.7.
321
322=head3 Standalone server mode
323
324 server.document-root = "/var/www/MyApp/root"
325
326 fastcgi.server = (
327 "" => (
328 "MyApp" => (
329 "socket" => "/tmp/myapp.socket",
330 "check-local" => "disable"
331 )
332 )
333 )
334
335=head3 Static mode
198b0efa 336
337 server.document-root = "/var/www/MyApp/root"
338
339 fastcgi.server = (
340 "" => (
341 "MyApp" => (
342 "socket" => "/tmp/myapp.socket",
343 "check-local" => "disable",
344 "bin-path" => "/var/www/MyApp/script/myapp_fastcgi.pl",
345 "min-procs" => 2,
346 "max-procs" => 5,
347 "idle-timeout" => 20
348 )
349 )
350 )
351
d7d72ad9 352Note that in newer versions of lighttpd, the min-procs and idle-timeout
353values are disabled. The above example would start 5 processes.
25810c41 354
d7d72ad9 355=head3 Non-root configuration
25810c41 356
d7d72ad9 357You can also run your application at any non-root location with either of the
358above modes.
198b0efa 359
360 fastcgi.server = (
d7d72ad9 361 "/myapp" => (
198b0efa 362 "MyApp" => (
d7d72ad9 363 # same as above
198b0efa 364 )
365 )
366 )
367
368For more information on using FastCGI under Lighttpd, visit
369L<http://www.lighttpd.net/documentation/fastcgi.html>
370
371=head2 IIS
372
373It is possible to run Catalyst under IIS with FastCGI, but we do not
374yet have detailed instructions.
375
fbcc39ad 376=head1 SEE ALSO
e2fd5b5f 377
fbcc39ad 378L<Catalyst>, L<FCGI>.
cd3bb248 379
fbcc39ad 380=head1 AUTHORS
ffb41d94 381
fbcc39ad 382Sebastian Riedel, <sri@cpan.org>
ffb41d94 383
fbcc39ad 384Christian Hansen, <ch@ngmedia.com>
ffb41d94 385
fbcc39ad 386Andy Grundman, <andy@hybridized.org>
ffb41d94 387
d7d72ad9 388=head1 THANKS
389
390Bill Moseley, for documentation updates and testing.
391
ffb41d94 392=head1 COPYRIGHT
393
394This program is free software, you can redistribute it and/or modify it under
395the same terms as Perl itself.
396
397=cut