Added pidfile option to FastCGI server
[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 use FCGI;
6
7 =head1 NAME
8
9 Catalyst::Engine::FastCGI - FastCGI Engine
10
11 =head1 DESCRIPTION
12
13 This is the FastCGI engine.
14
15 =head1 OVERLOADED METHODS
16
17 This class overloads some methods from C<Catalyst::Engine::CGI>.
18
19 =over 4
20
21 =item $self->run($c, $listen, { option => value, ... })
22  
23 Starts the FastCGI server.  If C<$listen> is set, then it specifies a
24 location to listen for FastCGI requests;
25
26   Form            Meaning
27   /path           listen via Unix sockets on /path
28   :port           listen via TCP on port on all interfaces
29   hostname:port   listen via TCP on port bound to hostname
30
31 Options may also be specified;
32
33   Option          Meaning
34   leave_umask     Set to 1 to disable setting umask to 0
35                   for socket open
36   nointr          Do not allow the listener to be
37                   interrupted by Ctrl+C
38   nproc           Specify a number of processes for
39                   FCGI::ProcManager
40   pidfile         Specify a filename for the pid file
41
42 =cut
43
44 sub run {
45     my ( $self, $class, $listen, $options ) = @_;
46
47     my $sock;
48     if ($listen) {
49         my $old_umask = umask;
50         unless ( $options->{leave_umask} ) {
51             umask(0);
52         }
53         $sock = FCGI::OpenSocket( $listen, 100 )
54           or die "failed to open FastCGI socket; $!";
55         unless ( $options->{leave_umask} ) {
56             umask($old_umask);
57         }
58     }
59     else {
60         -S STDIN
61           or die "STDIN is not a socket; specify a listen location";
62     }
63
64     $options ||= {};
65     
66     my %env;
67
68     my $request =
69       FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%env, $sock,
70         ( $options->{nointr} ? 0 : &FCGI::FAIL_ACCEPT_ON_INTR ),
71       );
72
73     my $proc_manager;
74     
75     if ( $listen ) {
76         require FCGI::ProcManager;
77         $options->{nproc} ||= 1;
78         
79         $proc_manager
80             = FCGI::ProcManager->new( { n_processes => $options->{nproc} } );
81           
82         if ( $options->{pidfile} ) {
83             $proc_manager->pm_write_pid_file( $options->{pidfile} );
84         }
85         
86         $proc_manager->pm_manage();
87     }
88
89     while ( $request->Accept >= 0 ) {
90         $proc_manager && $proc_manager->pm_pre_dispatch();
91         $class->handle_request( env => \%env );
92         $proc_manager && $proc_manager->pm_pre_dispatch();
93     }
94 }
95
96 =item $self->write($c, $buffer)
97
98 =cut
99
100 sub write {
101     my ( $self, $c, $buffer ) = @_;
102
103     unless ( $self->{_prepared_write} ) {
104         $self->prepare_write($c);
105         $self->{_prepared_write} = 1;
106     }
107
108     # FastCGI does not stream data properly if using 'print $handle',
109     # but a syswrite appears to work properly.
110     *STDOUT->syswrite($buffer);
111 }
112
113 1;
114 __END__
115
116 =back
117
118 =head1 WEB SERVER CONFIGURATIONS
119
120 =head2 Apache 1.x, 2.x
121
122 Apache requires the mod_fastcgi module.  The following config will let Apache
123 control the running of your FastCGI processes.
124
125     # Launch the FastCGI processes
126     FastCgiIpcDir /tmp
127     FastCgiServer /var/www/MyApp/script/myapp_fastcgi.pl -idle-timeout 300 -processes 5
128     
129     <VirtualHost *>
130         ScriptAlias / /var/www/MyApp/script/myapp_fastcgi.pl/
131     </VirtualHost>
132     
133 You can also tell Apache to connect to an external FastCGI server:
134
135     # Start the external server (requires FCGI::ProcManager)
136     $ script/myapp_fastcgi.pl -l /tmp/myapp.socket -n 5
137     
138     # Note that the path used in FastCgiExternalServer can be any path
139     FastCgiIpcDir /tmp
140     FastCgiExternalServer /tmp/myapp_fastcgi.pl -socket /tmp/myapp.socket
141     
142     <VirtualHost *>
143         ScriptAlias / /tmp/myapp_fastcgi.pl/
144     </VirtualHost>
145     
146 For more information on using FastCGI under Apache, visit
147 L<http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html>
148
149 =head2 Lighttpd
150
151 This configuration was tested with Lighttpd 1.4.7.
152
153     server.document-root = "/var/www/MyApp/root"
154     
155     fastcgi.server = (
156         "" => (
157             "MyApp" => (
158                 "socket"       => "/tmp/myapp.socket",
159                 "check-local"  => "disable",
160                 "bin-path"     => "/var/www/MyApp/script/myapp_fastcgi.pl",
161                 "min-procs"    => 2,
162                 "max-procs"    => 5,
163                 "idle-timeout" => 20
164             )
165         )
166     )
167     
168 You can also run your application at any non-root location.
169
170     fastcgi.server = (
171         "/myapp" => (
172             "MyApp" => (
173                 # same as above
174             )
175         )
176     )
177     
178 You can also use an external server:
179
180     # Start the external server (requires FCGI::ProcManager)
181     $ script/myapp_fastcgi.pl -l /tmp/myapp.socket -n 5
182
183     server.document-root = "/var/www/MyApp/root"
184
185     fastcgi.server = (
186         "" => (
187             "MyApp" => (
188                 "socket"      => "/tmp/myapp.socket",
189                 "check-local" => "disable"
190             )
191         )
192     )
193
194 For more information on using FastCGI under Lighttpd, visit
195 L<http://www.lighttpd.net/documentation/fastcgi.html>
196
197 =head2 IIS
198
199 It is possible to run Catalyst under IIS with FastCGI, but we do not
200 yet have detailed instructions.
201
202 =head1 SEE ALSO
203
204 L<Catalyst>, L<FCGI>.
205
206 =head1 AUTHORS
207
208 Sebastian Riedel, <sri@cpan.org>
209
210 Christian Hansen, <ch@ngmedia.com>
211
212 Andy Grundman, <andy@hybridized.org>
213
214 =head1 COPYRIGHT
215
216 This program is free software, you can redistribute it and/or modify it under
217 the same terms as Perl itself.
218
219 =cut