#!bin/tarbaby #ABSTRACT: PSGI application which simplifies migrating legacy/cgi applications to PSGI, but also has advanced features for normal psgi apps use strict; use warnings; use Cwd; use FindBin::libs; use File::Basename qw{dirname}; use TPSGI; my %options = main(@ARGV); =head1 USAGE tpsgi ... starman options tpsgi obeys a config file, ~/.tpsgi.ini which is in Config::Simple (key=value) format, with the keys being: verbose # Whether to print all log messages or not custom_log # Custom location for default (rotated) log routers # Router module(s), separate with comma. Relative to TPSGI install dir. indices # Dirindex files. In addition to index.html, index.htm, index.cgi loggers # Logger module(s), separate with comma auth # Authentication module domain # Domain name of the application, used by things like service files basedir # Directory you want to chdir into on startup. Relative to TPSGI install dir. Default '.' user # Who to run as http_user # Who's proxying this application (used for statics) autoreload # Whether or not to automatically reload the application when library files change. Default 0. The idea is that this application is going to be run in a chroot with the user's homedir being the application dir. This is why the various paths asked for are relative to the tPSGI install dir. =cut sub main { my (@args) = @_; my %options = TPSGI::get_config(); foreach my $route (@{$options{routers}}) { my $libdir = dirname($route); push(@INC, $libdir); } return %options; } our $app = sub { umask 0022; # Change your dir into whatever basedir you need to be in chdir("$options{tpsgi_dir}/$options{basedir}") or die "Can't chdir into $options{tpsgi_dir}/$options{'basedir'}: $!"; # Profiler is opt-in: set NYTPROF env var to enable. # The default path is used when NYTPROF is set without a file= clause. if ($ENV{NYTPROF}) { $ENV{NYTPROF} = "sigexit=1:savesrc=0:start=no:file=$options{tpsgi_dir}/prof/nytprof.out" unless $ENV{NYTPROF} =~ /file=/; require Devel::NYTProf; mkdir "$options{tpsgi_dir}/prof"; } my $self = TPSGI->new(%options); # TPSGI::app already catches all _app exceptions internally. # This outer eval is a last-resort safety net only. my $result = eval { $self->app(@_) }; return $result if defined $result; my $env = $_[0]; $env->{'psgi.errors'}->print($@) if $env && ref $env eq 'HASH' && $env->{'psgi.errors'}; return [500, ['Content-Type', 'text/plain', 'Content-Length', 21], ['Internal Server Error']]; };