Reformatted documentation
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Engine / FastCGI.pm
1 package Catalyst::Engine::FastCGI;
2
3 use strict;
4 use base 'Catalyst::Engine::CGI';
5 eval "use FCGI";
6 die "Please install FCGI\n" if $@;
7
8 =head1 NAME
9
10 Catalyst::Engine::FastCGI - FastCGI Engine
11
12 =head1 DESCRIPTION
13
14 This is the FastCGI engine.
15
16 =head1 OVERLOADED METHODS
17
18 This class overloads some methods from C<Catalyst::Engine::CGI>.
19
20 =head2 $self->run($c, $listen, { option => value, ... })
21  
22 Starts the FastCGI server.  If C<$listen> is set, then it specifies a
23 location 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
30 Options 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
39   pidfile         Specify a filename for the pid file
40   manager         Specify a FCGI::ProcManager sub-class
41   detach          Detach from console
42
43 =cut
44
45 sub run {
46     my ( $self, $class, $listen, $options ) = @_;
47
48     my $sock;
49     if ($listen) {
50         my $old_umask = umask;
51         unless ( $options->{leave_umask} ) {
52             umask(0);
53         }
54         $sock = FCGI::OpenSocket( $listen, 100 )
55           or die "failed to open FastCGI socket; $!";
56         unless ( $options->{leave_umask} ) {
57             umask($old_umask);
58         }
59     }
60     else {
61         -S STDIN
62           or die "STDIN is not a socket; specify a listen location";
63     }
64
65     $options ||= {};
66
67     my %env;
68
69     my $request =
70       FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%env, $sock,
71         ( $options->{nointr} ? 0 : &FCGI::FAIL_ACCEPT_ON_INTR ),
72       );
73
74     my $proc_manager;
75
76     if ($listen) {
77         $options->{manager} ||= "FCGI::ProcManager";
78         $options->{nproc}   ||= 1;
79
80         $self->daemon_fork() if $options->{detach};
81
82         if ( $options->{manager} ) {
83             eval "use $options->{manager}; 1" or die $@;
84
85             $proc_manager = $options->{manager}->new(
86                 {
87                     n_processes => $options->{nproc},
88                     pid_fname   => $options->{pidfile},
89                 }
90             );
91
92             # detach *before* the ProcManager inits
93             $self->daemon_detach() if $options->{detach};
94
95             $proc_manager->pm_manage();
96         }
97         elsif ( $options->{detach} ) {
98             $self->daemon_detach();
99         }
100     }
101
102     while ( $request->Accept >= 0 ) {
103         $proc_manager && $proc_manager->pm_pre_dispatch();
104         $class->handle_request( env => \%env );
105         $proc_manager && $proc_manager->pm_pre_dispatch();
106     }
107 }
108
109 =head2 $self->write($c, $buffer)
110
111 =cut
112
113 sub write {
114     my ( $self, $c, $buffer ) = @_;
115
116     unless ( $self->{_prepared_write} ) {
117         $self->prepare_write($c);
118         $self->{_prepared_write} = 1;
119     }
120
121     # FastCGI does not stream data properly if using 'print $handle',
122     # but a syswrite appears to work properly.
123     *STDOUT->syswrite($buffer);
124 }
125
126 =head2 $self->daemon_fork()
127
128 Performs the first part of daemon initialisation.  Specifically,
129 forking.  STDERR, etc are still connected to a terminal.
130
131 =cut
132
133 sub daemon_fork {
134     require POSIX;
135     fork && exit;
136 }
137
138 =head2 $self->daemon_detach( )
139
140 Performs the second part of daemon initialisation.  Specifically,
141 disassociates from the terminal.
142
143 However, this does B<not> change the current working directory to "/",
144 as normal daemons do.  It also does not close all open file
145 descriptors (except STDIN, STDOUT and STDERR, which are re-opened from
146 F</dev/null>).
147
148 =cut
149
150 sub daemon_detach {
151     my $self = shift;
152     print "FastCGI daemon started (pid $$)\n";
153     open STDIN,  "+</dev/null" or die $!;
154     open STDOUT, ">&STDIN"     or die $!;
155     open STDERR, ">&STDIN"     or die $!;
156     POSIX::setsid();
157 }
158
159 1;
160 __END__
161
162 =head1 WEB SERVER CONFIGURATIONS
163
164 =head2 Apache 1.x, 2.x
165
166 Apache requires the mod_fastcgi module.  The following config will let Apache
167 control the running of your FastCGI processes.
168
169     # Launch the FastCGI processes
170     FastCgiIpcDir /tmp
171     FastCgiServer /var/www/MyApp/script/myapp_fastcgi.pl -idle-timeout 300 -processes 5
172     
173     <VirtualHost *>
174         ScriptAlias / /var/www/MyApp/script/myapp_fastcgi.pl/
175     </VirtualHost>
176     
177 You can also tell Apache to connect to an external FastCGI server:
178
179     # Start the external server (requires FCGI::ProcManager)
180     $ script/myapp_fastcgi.pl -l /tmp/myapp.socket -n 5
181     
182     # Note that the path used in FastCgiExternalServer can be any path
183     FastCgiIpcDir /tmp
184     FastCgiExternalServer /tmp/myapp_fastcgi.pl -socket /tmp/myapp.socket
185     
186     <VirtualHost *>
187         ScriptAlias / /tmp/myapp_fastcgi.pl/
188     </VirtualHost>
189     
190 For more information on using FastCGI under Apache, visit
191 L<http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html>
192
193 =head2 Lighttpd
194
195 This configuration was tested with Lighttpd 1.4.7.
196
197     server.document-root = "/var/www/MyApp/root"
198     
199     fastcgi.server = (
200         "" => (
201             "MyApp" => (
202                 "socket"       => "/tmp/myapp.socket",
203                 "check-local"  => "disable",
204                 "bin-path"     => "/var/www/MyApp/script/myapp_fastcgi.pl",
205                 "min-procs"    => 2,
206                 "max-procs"    => 5,
207                 "idle-timeout" => 20
208             )
209         )
210     )
211     
212 You can also run your application at any non-root location.
213
214     fastcgi.server = (
215         "/myapp" => (
216             "MyApp" => (
217                 # same as above
218             )
219         )
220     )
221     
222 You can also use an external server:
223
224     # Start the external server (requires FCGI::ProcManager)
225     $ script/myapp_fastcgi.pl -l /tmp/myapp.socket -n 5
226
227     server.document-root = "/var/www/MyApp/root"
228
229     fastcgi.server = (
230         "" => (
231             "MyApp" => (
232                 "socket"      => "/tmp/myapp.socket",
233                 "check-local" => "disable"
234             )
235         )
236     )
237
238 For more information on using FastCGI under Lighttpd, visit
239 L<http://www.lighttpd.net/documentation/fastcgi.html>
240
241 =head2 IIS
242
243 It is possible to run Catalyst under IIS with FastCGI, but we do not
244 yet have detailed instructions.
245
246 =head1 SEE ALSO
247
248 L<Catalyst>, L<FCGI>.
249
250 =head1 AUTHORS
251
252 Sebastian Riedel, <sri@cpan.org>
253
254 Christian Hansen, <ch@ngmedia.com>
255
256 Andy Grundman, <andy@hybridized.org>
257
258 =head1 COPYRIGHT
259
260 This program is free software, you can redistribute it and/or modify it under
261 the same terms as Perl itself.
262
263 =cut