diff options
Diffstat (limited to 'rt/sbin/standalone_httpd.in')
-rw-r--r-- | rt/sbin/standalone_httpd.in | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/rt/sbin/standalone_httpd.in b/rt/sbin/standalone_httpd.in new file mode 100644 index 000000000..b438202dd --- /dev/null +++ b/rt/sbin/standalone_httpd.in @@ -0,0 +1,282 @@ +#!@PERL@ -w +# BEGIN BPS TAGGED BLOCK {{{ +# +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC +# <sales@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 }}} +use warnings; +use strict; + +# fix lib paths, some may be relative +BEGIN { + die <<EOT if ${^TAINT}; +RT does not run under Perl's "taint mode". Remove -T from the command +line, or remove the PerlTaintCheck parameter from your mod_perl +configuration. +EOT + + require File::Spec; + my @libs = ("@RT_LIB_PATH@", "@LOCAL_LIB_PATH@"); + my $bin_path; + + for my $lib (@libs) { + unless ( File::Spec->file_name_is_absolute($lib) ) { + unless ($bin_path) { + if ( File::Spec->file_name_is_absolute(__FILE__) ) { + $bin_path = ( File::Spec->splitpath(__FILE__) )[1]; + } + else { + require FindBin; + no warnings "once"; + $bin_path = $FindBin::Bin; + } + } + $lib = File::Spec->catfile( $bin_path, File::Spec->updir, $lib ); + } + unshift @INC, $lib; + } + +} + +use Getopt::Long; +no warnings 'once'; + +if (grep { m/help/ } @ARGV) { + require Pod::Usage; + print Pod::Usage::pod2usage( { verbose => 2 } ); + exit; +} + +require RT; +RT->LoadConfig(); +require Module::Refresh if RT->Config->Get('DevelMode'); + +require RT::Handle; +my ($integrity, $state, $msg) = RT::Handle->CheckIntegrity; + +unless ( $integrity ) { + print STDERR <<EOF; + +RT couldn't connect to the database where tickets are stored. +If this is a new installation of RT, you should visit the URL below +to configure RT and initialize your database. + +If this is an existing RT installation, this may indicate a database +connectivity problem. + +The error RT got back when trying to connect to your database was: + +$msg + +EOF + + require RT::Installer; + # don't enter install mode if the file exists but is unwritable + if (-e RT::Installer->ConfigFile && !-w _) { + die 'Since your configuration exists (' + . RT::Installer->ConfigFile + . ") but is not writable, I'm refusing to do anything.\n"; + } + + RT->Config->Set( 'LexiconLanguages' => '*' ); + RT::I18N->Init; + + RT->InstallMode(1); +} else { + RT->Init(); + + my ($status, $msg) = RT::Handle->CheckCompatibility( $RT::Handle->dbh, 'post'); + unless ( $status ) { + print STDERR $msg, "\n\n"; + exit -1; + } +} + +# we must disconnect DB before fork +if ($RT::Handle) { + $RT::Handle->dbh(undef); + undef $RT::Handle; +} + +require RT::Interface::Web::Handler; +my $app = RT::Interface::Web::Handler->PSGIApp; + +if ($ENV{RT_TESTING}) { + my $screen_logger = $RT::Logger->remove('screen'); + require Log::Dispatch::Perl; + $RT::Logger->add( + Log::Dispatch::Perl->new( + name => 'rttest', + min_level => $screen_logger->min_level, + action => { + error => 'warn', + critical => 'warn' + } + ) + ); + require Plack::Middleware::Test::StashWarnings; + $app = Plack::Middleware::Test::StashWarnings->wrap($app); +} + +# when used as a psgi file +if (caller) { + return $app; +} + + +# load appropriate server + +require Plack::Runner; + +my $is_fastcgi = $0 =~ m/fcgi$/; +my $r = Plack::Runner->new( $0 =~ 'standalone' ? ( server => 'Standalone' ) : + $is_fastcgi ? ( server => 'FCGI' ) + : (), + env => 'deployment' ); + +# figure out the port +my $port; + +# handle "rt-server 8888" for back-compat, but complain about it +if ($ARGV[0] && $ARGV[0] =~ m/^\d+$/) { + warn "Deprecated: please run $0 --port $ARGV[0] instead\n"; + unshift @ARGV, '--port'; +} + +my @args = @ARGV; + +use List::MoreUtils 'last_index'; +my $last_index = last_index { $_ eq '--port' } @args; + +my $explicit_port; + +if ( $last_index != -1 && $args[$last_index+1] =~ /^\d+$/ ) { + $explicit_port = $args[$last_index+1]; + $port = $explicit_port; + + # inform the rest of the system what port we manually chose + my $old_app = $app; + $app = sub { + my $env = shift; + + $env->{'rt.explicit_port'} = $port; + + $old_app->($env, @_); + }; +} +else { + # default to the configured WebPort and inform Plack::Runner + $port = RT->Config->Get('WebPort') || '8080'; + push @args, '--port', $port; +} + +push @args, '--server', 'Standalone' if RT->InstallMode; +push @args, '--server', 'Starlet' unless $r->{server} || grep { m/--server/ } @args; + +$r->parse_options(@args); + +delete $r->{options} if $is_fastcgi; ### mangle_host_port_socket ruins everything + +unless ($r->{env} eq 'development') { + push @{$r->{options}}, server_ready => sub { + my($args) = @_; + my $name = $args->{server_software} || ref($args); # $args is $server + my $host = $args->{host} || 0; + my $proto = $args->{proto} || 'http'; + print STDERR "$name: Accepting connections at $proto://$host:$args->{port}/\n"; + }; +} +eval { $r->run($app) }; +if (my $err = $@) { + handle_startup_error($err); +} + +exit 0; + +sub handle_startup_error { + my $err = shift; + if ( $err =~ /listen/ ) { + handle_bind_error(); + } else { + die + "Something went wrong while trying to run RT's standalone web server:\n\t" + . $err; + } +} + + +sub handle_bind_error { + + print STDERR <<EOF; +WARNING: RT couldn't start up a web server on port @{[$port]}. +This is often the case if the port is already in use or you're running @{[$0]} +as someone other than your system's "root" user. You may also specify a +temporary port with: $0 --port <port> +EOF + + if ($explicit_port) { + print STDERR + "Please check your system configuration or choose another port\n\n"; + } +} + +__END__ + +=head1 NAME + +rt-server - RT standalone server + +=head1 SYNOPSIS + + # runs prefork server listening on port 8080, requires Starlet + rt-server --port 8080 + + # runs server listening on port 8080 + rt-server --server Standalone --port 8080 + # or + standalone_httpd --port 8080 + + # runs other PSGI server on port 8080 + rt-server --server Starman --port 8080 |