doc improvements
[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";
6die "Please install FCGI\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)
100 if $options->{keep_stderr}; # (if asked to)
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
240 FastCgiExternalServer /tmp/myapp -socket /tmp/myapp.socket
241 Alias /myapp/ /tmp/myapp/
242
243 # Or, run at the root
244 Alias / /tmp/myapp/
245
246 # Optionally, rewrite the path when accessed without a trailing slash
247 RewriteRule ^/myapp$ myapp/ [R]
248
249The FastCgiExternalServer directive tells Apache that when serving /tmp/myapp
250to use the FastCGI application listenting on the socket /tmp/mapp.socket.
251Note that /tmp/myapp does not need to exist -- it's a virtual file name.
252
253It's likely that Apache is not configured to serve files in /tmp, so the
254Alias directive maps the url path /myapp/ to the (virtual) file that runs the
255FastCGI application. The trailing slashes are important as their use will
256correctly set the PATH_INFO environment variable used by Catalyst to
257determine the request path. If you would like to be able to access your app
258without a trailing slash (http://server/myapp), you can use the above
259RewriteRule directive.
260
261=head3 Static mode
262
263The term 'static' is misleading, but in static mode Apache uses its own
264FastCGI Process Manager to start the application processes. This happens at
265Apache startup time. In this case you do not run your application's
266fastcgi.pl script -- that is done by Apache. Apache then maps URIs to the
267FastCGI script to run your application.
268
269 FastCgiServer /path/to/myapp/script/myapp_fastcgi.pl -processes 3
270 Alias /myapp/ /path/to/myapp/script/myapp_fastcgi.pl/
198b0efa 271
d7d72ad9 272FastCgiServer tells Apache to start three processes of your application at
273startup. The Alias command maps a path to the FastCGI application. Again,
274the trailing slashes are important.
198b0efa 275
d7d72ad9 276=head3 Dynamic mode
277
278In FastCGI dynamic mode, Apache will run your application on demand,
279typically by requesting a file with a specific extension (e.g. .fcgi). ISPs
280often use this type of setup to provide FastCGI support to many customers.
281
282In this mode it is often enough to place or link your *_fastcgi.pl script in
283your cgi-bin directory with the extension of .fcgi. In dynamic mode Apache
284must be able to run your application as a CGI script so ExecCGI must be
285enabled for the directory.
286
287 AddHandler fastcgi-script .fcgi
288
289The above tells Apache to run any .fcgi file as a FastCGI application.
290
291Here is a complete example:
292
293 <VirtualHost *:80>
294 ServerName www.myapp.com
295 DocumentRoot /path/to/MyApp
296
297 # Allow CGI script to run
298 <Directory /path/to/MyApp>
299 Options +ExecCGI
300 </Directory>
301
302 # Tell Apache this is a FastCGI application
303 <Files myapp_fastcgi.pl>
304 SetHandler fastcgi-script
305 </Files>
198b0efa 306 </VirtualHost>
d7d72ad9 307
308Then a request for /script/myapp_fastcgi.pl will run the
309application.
198b0efa 310
311For more information on using FastCGI under Apache, visit
312L<http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html>
313
314=head2 Lighttpd
315
d7d72ad9 316These configurations were tested with Lighttpd 1.4.7.
317
318=head3 Standalone server mode
319
320 server.document-root = "/var/www/MyApp/root"
321
322 fastcgi.server = (
323 "" => (
324 "MyApp" => (
325 "socket" => "/tmp/myapp.socket",
326 "check-local" => "disable"
327 )
328 )
329 )
330
331=head3 Static mode
198b0efa 332
333 server.document-root = "/var/www/MyApp/root"
334
335 fastcgi.server = (
336 "" => (
337 "MyApp" => (
338 "socket" => "/tmp/myapp.socket",
339 "check-local" => "disable",
340 "bin-path" => "/var/www/MyApp/script/myapp_fastcgi.pl",
341 "min-procs" => 2,
342 "max-procs" => 5,
343 "idle-timeout" => 20
344 )
345 )
346 )
347
d7d72ad9 348Note that in newer versions of lighttpd, the min-procs and idle-timeout
349values are disabled. The above example would start 5 processes.
25810c41 350
d7d72ad9 351=head3 Non-root configuration
25810c41 352
d7d72ad9 353You can also run your application at any non-root location with either of the
354above modes.
198b0efa 355
356 fastcgi.server = (
d7d72ad9 357 "/myapp" => (
198b0efa 358 "MyApp" => (
d7d72ad9 359 # same as above
198b0efa 360 )
361 )
362 )
363
364For more information on using FastCGI under Lighttpd, visit
365L<http://www.lighttpd.net/documentation/fastcgi.html>
366
367=head2 IIS
368
369It is possible to run Catalyst under IIS with FastCGI, but we do not
370yet have detailed instructions.
371
fbcc39ad 372=head1 SEE ALSO
e2fd5b5f 373
fbcc39ad 374L<Catalyst>, L<FCGI>.
cd3bb248 375
fbcc39ad 376=head1 AUTHORS
ffb41d94 377
fbcc39ad 378Sebastian Riedel, <sri@cpan.org>
ffb41d94 379
fbcc39ad 380Christian Hansen, <ch@ngmedia.com>
ffb41d94 381
fbcc39ad 382Andy Grundman, <andy@hybridized.org>
ffb41d94 383
d7d72ad9 384=head1 THANKS
385
386Bill Moseley, for documentation updates and testing.
387
ffb41d94 388=head1 COPYRIGHT
389
390This program is free software, you can redistribute it and/or modify it under
391the same terms as Perl itself.
392
393=cut