diff options
Diffstat (limited to 'rt/bin/fastcgi_server')
-rwxr-xr-x | rt/bin/fastcgi_server | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/rt/bin/fastcgi_server b/rt/bin/fastcgi_server new file mode 100755 index 000000000..7c0935dfe --- /dev/null +++ b/rt/bin/fastcgi_server @@ -0,0 +1,252 @@ +#!/usr/bin/perl +# BEGIN BPS TAGGED BLOCK {{{ +# +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC +# <jesse@bestpractical.com> +# +# (Except where explicitly superseded by other copyright notices) +# +# +# LICENSE: +# +# This work is made available to you under the terms of Version 2 of +# the GNU General Public License. A copy of that license should have +# been provided with this software, but in any event can be snarfed +# from www.gnu.org. +# +# This work is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 or visit their web page on the internet at +# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +# +# +# CONTRIBUTION SUBMISSION POLICY: +# +# (The following paragraph is not intended to limit the rights granted +# to you to modify and distribute this software under the terms of +# the GNU General Public License and is only of importance to you if +# you choose to contribute your changes and enhancements to the +# community by submitting them to Best Practical Solutions, LLC.) +# +# By intentionally submitting any modifications, corrections or +# derivatives to this work, or any other work intended for use with +# Request Tracker, to Best Practical Solutions, LLC, you confirm that +# you are the copyright holder for those contributions and you grant +# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, +# royalty-free, perpetual, license to use, copy, create derivative +# works based on those contributions, and sublicense and distribute +# those contributions and any derivatives thereof. +# +# END BPS TAGGED BLOCK }}} + +=head1 NAME + +fastcgi_server - external FastCGI server for RT + +=head1 USAGE + + # get help + fastcgi_server -h + + # start a server using defaults + fastcgi_server + + # start server with custom option + fastcgi_server --socket /path/to/socket -n 5 + fastcgi_server --port 12345 -n 5 + +=head1 DESCRIPTION + +This is a forking external FastCGI server for RT, it can be used +with apache and other servers supporting FastCGI technology. + +An advantage is lower memory usage because of sharing memory +between process. It's easier to setup this with nginx and other +servers that can not maintain pool of fastcgi servers, apache +can do this. + +Disadvantage is that you have to start this server yourself and +monitor it, web servers wouldn't be able to restart it on crash. + +=head1 OPTIONS + +=over 4 + +=item -h, --help - get help + +=item -n, --nprocesses - number of processes to start, by default 10 + +=item -s, --socket - socket path, by default F<RT/var/path/fastcgi.sock> +usually F</opt/rt3/var/fastcgi.sock>. + +=item -p, --port - port to use instead of socket, by default socket is +used. + +=item --pidfile - pid file path, by default F<RT/var/path/fastcgi.pid>. + +=back + +=head1 SERVER CONFIGURATION + +=head2 nginx + +Below you can find example of minimal config for nginx to run RT +with this FastCGI server. It's not ideal, but a good enough start. + + worker_processes 1; + events { worker_connections 1024; } + + pid /opt/rt3/var/nginx/server.pid; + error_log /opt/rt3/var/nginx/error.log debug; + + http { + access_log /opt/rt3/var/nginx/access.log; + + server { + listen 8080; + server_name localhost; + + location / { + root /opt/rt3/share/html; + fastcgi_pass unix:/opt/rt3/var/fastcgi.sock; + + fastcgi_param QUERY_STRING $query_string; + fastcgi_param REQUEST_METHOD $request_method; + fastcgi_param CONTENT_TYPE $content_type; + fastcgi_param CONTENT_LENGTH $content_length; + fastcgi_param PATH_INFO $fastcgi_script_name; + } + + location /NoAuth/images/ { + alias /opt/rt3/share/html/NoAuth/images/; + } + } + } + +=head1 lighttpd + +Server config: + + server.name = "localhost" + server.port = 80 + + server.username = "rt_web_user" + server.groupname = "rt_web_group" + + server.pid-file = "/opt/rt3/var/lighthttpd/server.pid" + server.errorlog = "/opt/rt3/var/lighthttpd/error.log" + + server.document-root = "/opt/rt3/share/html" + + server.modules = ( "mod_fastcgi" ) + fastcgi.server = ( + "/" => (( + "socket" => "/opt/rt3/var/fastcgi.sock", + "check-local" => "disable", + "fix-root-scriptname" => "enable", + )) + ) + +=cut + + +use strict; +use warnings; +no warnings qw(once); + +package RT::Interface::Web::FCGI::Server; +use base qw(FCGI::ProcManager); + +package main; + +use Getopt::Long; + +my %opt = ( + help => 0, + socket => '', + port => 0, + nprocesses => 10, + pidfile => '', +); + +GetOptions( + 'h|help!' => \$opt{'help'}, + 's|socket=s' => \$opt{'socket'}, + 'p|port=s' => \$opt{'port'}, + 'n|nprocesses=s' => \$opt{'nprocesses'}, + 'pidfile=s' => \$opt{'pidfile'}, +); + +if ( $opt{'help'} ) { + require Pod::Usage; + Pod::Usage::pod2usage( + -message => "", + -exitval => $opt{'help'}? 0 : 1, + -verbose => 99, + -sections => $opt{'help'}? 'NAME|USAGE|DESCRIPTION|OPTIONS' : 'NAME|USAGE', + ); +} + +$ENV{'RT_WEBMUX_HEAVY_LOAD'} = 1; +use File::Basename; +require (dirname(__FILE__) .'/webmux.pl'); + +unless ( $opt{'socket'} && $opt{'port'} ) { + require File::Spec; + $opt{'socket'} = File::Spec->catfile($RT::VarPath, 'fastcgi.sock'); +} +elsif ( $opt{'port'} ) { + $opt{'socket'} = ':'. $opt{'port'}; +} +$ENV{'FCGI_SOCKET_PATH'} = $opt{'socket'}; + +$opt{'pidfile'} ||= File::Spec->catfile($RT::VarPath, 'fastcgi.pid'); + +require CGI::Fast; + +my $proc_manager = RT::Interface::Web::FCGI::Server->new({ + n_processes => $opt{'nprocesses'} || 10, + pid_fname => $opt{'pidfile'}, +}); + +$proc_manager->pm_manage(); + +while ( my $cgi = CGI::Fast->new ) { + $proc_manager->pm_pre_dispatch; + + $ENV{'PATH'} = '/bin:/usr/bin'; + $ENV{'CDPATH'} = '' if defined $ENV{'CDPATH'}; + $ENV{'SHELL'} = '/bin/sh' if defined $ENV{'SHELL'}; + $ENV{'ENV'} = '' if defined $ENV{'ENV'}; + $ENV{'IFS'} = '' if defined $ENV{'IFS'}; + + Module::Refresh->refresh if RT->Config->Get('DevelMode'); + RT::ConnectToDatabase(); + + my $interp = $RT::Mason::Handler->interp; + if ( + !$interp->comp_exists( $cgi->path_info ) + && $interp->comp_exists( $cgi->path_info . "/index.html" ) + ) { + $cgi->path_info( $cgi->path_info . "/index.html" ); + } + + local $@; + eval { $RT::Mason::Handler->handle_cgi_object($cgi); }; + if ($@) { + $RT::Logger->crit($@); + } + RT::Interface::Web::Handler->CleanupRequest; + + $proc_manager->pm_post_dispatch; +} + +1; |