#!/usr/bin/perl -w # BEGIN BPS TAGGED BLOCK {{{ # # COPYRIGHT: # # This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC # # # (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 <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(); RT->InitLogging(); require Module::Refresh if RT->Config->Get('DevelMode'); require RT::Handle; my ($integrity, $state, $msg) = RT::Handle->CheckIntegrity; unless ( $integrity ) { print STDERR <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 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