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