import rt 3.8.8
[freeside.git] / rt / bin / fastcgi_server.in
1 #!@PERL@
2 # BEGIN BPS TAGGED BLOCK {{{
3
4 # COPYRIGHT:
5
6 # This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
7 #                                          <jesse@bestpractical.com>
8
9 # (Except where explicitly superseded by other copyright notices)
10
11
12 # LICENSE:
13
14 # This work is made available to you under the terms of Version 2 of
15 # the GNU General Public License. A copy of that license should have
16 # been provided with this software, but in any event can be snarfed
17 # from www.gnu.org.
18
19 # This work is distributed in the hope that it will be useful, but
20 # WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22 # General Public License for more details.
23
24 # You should have received a copy of the GNU General Public License
25 # along with this program; if not, write to the Free Software
26 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
27 # 02110-1301 or visit their web page on the internet at
28 # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
29
30
31 # CONTRIBUTION SUBMISSION POLICY:
32
33 # (The following paragraph is not intended to limit the rights granted
34 # to you to modify and distribute this software under the terms of
35 # the GNU General Public License and is only of importance to you if
36 # you choose to contribute your changes and enhancements to the
37 # community by submitting them to Best Practical Solutions, LLC.)
38
39 # By intentionally submitting any modifications, corrections or
40 # derivatives to this work, or any other work intended for use with
41 # Request Tracker, to Best Practical Solutions, LLC, you confirm that
42 # you are the copyright holder for those contributions and you grant
43 # Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
44 # royalty-free, perpetual, license to use, copy, create derivative
45 # works based on those contributions, and sublicense and distribute
46 # those contributions and any derivatives thereof.
47
48 # END BPS TAGGED BLOCK }}}
49
50 =head1 NAME
51
52 fastcgi_server - external FastCGI server for RT
53
54 =head1 USAGE
55
56     # get help
57     fastcgi_server -h
58
59     # start a server using defaults
60     fastcgi_server
61
62     # start server with custom option
63     fastcgi_server --socket /path/to/socket -n 5
64     fastcgi_server --port 12345 -n 5
65
66 =head1 DESCRIPTION
67
68 This is a forking external FastCGI server for RT, it can be used
69 with apache and other servers supporting FastCGI technology.
70
71 An advantage is lower memory usage because of sharing memory
72 between process. It's easier to setup this with nginx and other
73 servers that can not maintain pool of fastcgi servers, apache
74 can do this.
75
76 Disadvantage is that you have to start this server yourself and
77 monitor it, web servers wouldn't be able to restart it on crash.
78
79 =head1 OPTIONS
80
81 =over 4
82
83 =item -h, --help - get help
84
85 =item -n, --nprocesses - number of processes to start, by default 10
86
87 =item -s, --socket - socket path, by default F<RT/var/path/fastcgi.sock>
88 usually F</opt/rt3/var/fastcgi.sock>.
89
90 =item -p, --port - port to use instead of socket, by default socket is
91 used.
92
93 =item --pidfile - pid file path, by default F<RT/var/path/fastcgi.pid>.
94
95 =back
96
97 =head1 SERVER CONFIGURATION
98
99 =head2 nginx
100
101 Below you can find example of minimal config for nginx to run RT
102 with this FastCGI server. It's not ideal, but a good enough start.
103
104     worker_processes  1;
105     events { worker_connections  1024; }
106
107     pid         /opt/rt3/var/nginx/server.pid;
108     error_log   /opt/rt3/var/nginx/error.log debug;
109
110     http {
111         access_log  /opt/rt3/var/nginx/access.log;
112
113         server {
114             listen       8080;
115             server_name  localhost;
116
117             location / {
118                 root           /opt/rt3/share/html;
119                 fastcgi_pass   unix:/opt/rt3/var/fastcgi.sock;
120
121                 fastcgi_param  QUERY_STRING       $query_string;
122                 fastcgi_param  REQUEST_METHOD     $request_method;
123                 fastcgi_param  CONTENT_TYPE       $content_type;
124                 fastcgi_param  CONTENT_LENGTH     $content_length;
125                 fastcgi_param  PATH_INFO          $fastcgi_script_name;
126             }
127
128             location /NoAuth/images/ {
129                 alias   /opt/rt3/share/html/NoAuth/images/;
130             }
131         }
132     }
133
134 =head1 lighttpd
135
136 Server config:
137
138     server.name = "localhost"
139     server.port = 80
140
141     server.username  = "rt_web_user"
142     server.groupname = "rt_web_group"
143
144     server.pid-file = "/opt/rt3/var/lighthttpd/server.pid"
145     server.errorlog = "/opt/rt3/var/lighthttpd/error.log"
146
147     server.document-root = "/opt/rt3/share/html"
148
149     server.modules = ( "mod_fastcgi" )
150     fastcgi.server = (
151         "/" => ((
152             "socket" => "/opt/rt3/var/fastcgi.sock",
153             "check-local" => "disable",
154             "fix-root-scriptname" => "enable",
155         ))
156     )
157
158 =cut
159
160
161 use strict;
162 use warnings;
163 no warnings qw(once);
164
165 package RT::Interface::Web::FCGI::Server;
166 use base qw(FCGI::ProcManager);
167
168 package main;
169
170 use Getopt::Long;
171
172 my %opt = (
173     help       => 0,
174     socket     => '',
175     port       => 0,
176     nprocesses => 10,
177     pidfile    => '',
178 );
179
180 GetOptions(
181     'h|help!'        => \$opt{'help'},
182     's|socket=s'     => \$opt{'socket'},
183     'p|port=s'       => \$opt{'port'},
184     'n|nprocesses=s' => \$opt{'nprocesses'},
185     'pidfile=s'      => \$opt{'pidfile'},
186 );
187
188 if ( $opt{'help'} ) {
189     require Pod::Usage;
190     Pod::Usage::pod2usage(
191         -message => "",
192         -exitval => $opt{'help'}? 0 : 1,
193         -verbose => 99,
194         -sections => $opt{'help'}? 'NAME|USAGE|DESCRIPTION|OPTIONS' : 'NAME|USAGE',
195     );
196 }
197
198 $ENV{'RT_WEBMUX_HEAVY_LOAD'} = 1;
199 use File::Basename;
200 require (dirname(__FILE__) .'/webmux.pl');
201
202 unless ( $opt{'socket'} && $opt{'port'} ) {
203     require File::Spec;
204     $opt{'socket'} = File::Spec->catfile($RT::VarPath, 'fastcgi.sock');
205 }
206 elsif ( $opt{'port'} ) {
207     $opt{'socket'} = ':'. $opt{'port'};
208 }
209 $ENV{'FCGI_SOCKET_PATH'} = $opt{'socket'};
210
211 $opt{'pidfile'} ||= File::Spec->catfile($RT::VarPath, 'fastcgi.pid');
212
213 require CGI::Fast;
214
215 my $proc_manager = RT::Interface::Web::FCGI::Server->new({
216     n_processes => $opt{'nprocesses'} || 10,
217     pid_fname   => $opt{'pidfile'},
218 });
219
220 $proc_manager->pm_manage();
221
222 while ( my $cgi = CGI::Fast->new ) {
223     $proc_manager->pm_pre_dispatch;
224
225     $ENV{'PATH'}   = '/bin:/usr/bin';
226     $ENV{'CDPATH'} = '' if defined $ENV{'CDPATH'};
227     $ENV{'SHELL'}  = '/bin/sh' if defined $ENV{'SHELL'};
228     $ENV{'ENV'}    = '' if defined $ENV{'ENV'};
229     $ENV{'IFS'}    = '' if defined $ENV{'IFS'};
230
231     Module::Refresh->refresh if RT->Config->Get('DevelMode');
232     RT::ConnectToDatabase();
233
234     my $interp = $RT::Mason::Handler->interp;
235     if (
236         !$interp->comp_exists( $cgi->path_info )
237         && $interp->comp_exists( $cgi->path_info . "/index.html" )
238     ) {
239         $cgi->path_info( $cgi->path_info . "/index.html" );
240     }
241
242     local $@;
243     eval { $RT::Mason::Handler->handle_cgi_object($cgi); };
244     if ($@) {
245         $RT::Logger->crit($@);
246     }
247     RT::Interface::Web::Handler->CleanupRequest;
248
249     $proc_manager->pm_post_dispatch;
250 }
251
252 1;