Plack
view release on metacpan or search on metacpan
lib/Plack/Handler/FCGI.pm view on Meta::CPAN
%env,
'psgi.version' => [1,1],
'psgi.url_scheme' => ($env{HTTPS}||'off') =~ /^(?:on|1)$/i ? 'https' : 'http',
'psgi.input' => $self->{stdin},
'psgi.errors' =>
($self->{keep_stderr} ? \*STDERR : $self->{stderr}),
'psgi.multithread' => Plack::Util::FALSE,
'psgi.multiprocess' => defined $proc_manager,
'psgi.run_once' => Plack::Util::FALSE,
'psgi.streaming' => Plack::Util::TRUE,
'psgi.nonblocking' => Plack::Util::FALSE,
'psgix.harakiri' => defined $proc_manager,
'psgix.cleanup' => 1,
'psgix.cleanup.handlers' => [],
};
delete $env->{HTTP_CONTENT_TYPE};
delete $env->{HTTP_CONTENT_LENGTH};
# lighttpd munges multiple slashes in PATH_INFO into one. Try recovering it
my $uri = URI->new("http://localhost" . $env->{REQUEST_URI});
$env->{PATH_INFO} = uri_unescape($uri->path);
$env->{PATH_INFO} =~ s/^\Q$env->{SCRIPT_NAME}\E//;
# root access for mod_fastcgi
if (!exists $env->{PATH_INFO}) {
$env->{PATH_INFO} = '';
}
# typical fastcgi_param from nginx might get empty values
for my $key (qw(CONTENT_TYPE CONTENT_LENGTH)) {
no warnings;
delete $env->{$key} if exists $env->{$key} && $env->{$key} eq '';
}
if (defined(my $HTTP_AUTHORIZATION = $env->{Authorization})) {
$env->{HTTP_AUTHORIZATION} = $HTTP_AUTHORIZATION;
}
my $res = Plack::Util::run_app $app, $env;
if (ref $res eq 'ARRAY') {
$self->_handle_response($res);
}
elsif (ref $res eq 'CODE') {
$res->(sub {
$self->_handle_response($_[0]);
});
}
else {
die "Bad response $res";
}
# give pm_post_dispatch the chance to do things after the client thinks
# the request is done
$request->Finish;
$proc_manager && $proc_manager->pm_post_dispatch();
# When the fcgi-manager exits it sends a TERM signal to the workers.
# However, if we're busy processing the cleanup handlers, testing
# shows that the worker doesn't actually exit in that case.
# Trapping the TERM signal and finshing up fixes that.
my $exit_due_to_signal = 0;
if ( @{ $env->{'psgix.cleanup.handlers'} || [] } ) {
local $SIG{TERM} = sub { $exit_due_to_signal = 1 };
for my $handler ( @{ $env->{'psgix.cleanup.handlers'} } ) {
$handler->($env);
}
}
if ($proc_manager && $env->{'psgix.harakiri.commit'}) {
$proc_manager->pm_exit("safe exit with harakiri");
}
elsif ($exit_due_to_signal) {
$proc_manager && $proc_manager->pm_exit("safe exit due to signal");
exit; # want to exit, even without a $proc_manager
}
}
}
sub _handle_response {
my ($self, $res) = @_;
$self->{stdout}->autoflush(1);
binmode $self->{stdout};
my $hdrs;
my $message = status_message($res->[0]);
$hdrs = "Status: $res->[0] $message\015\012";
my $headers = $res->[1];
while (my ($k, $v) = splice @$headers, 0, 2) {
$hdrs .= "$k: $v\015\012";
}
$hdrs .= "\015\012";
print { $self->{stdout} } $hdrs;
my $cb = sub { print { $self->{stdout} } $_[0] };
my $body = $res->[2];
if (defined $body) {
Plack::Util::foreach($body, $cb);
}
else {
return Plack::Util::inline_object
write => $cb,
close => sub { };
}
}
sub daemon_fork {
require POSIX;
fork && exit;
}
sub daemon_detach {
my $self = shift;
print "FastCGI daemon started (pid $$)\n";
open STDIN, "+</dev/null" or die $!; ## no critic
open STDOUT, ">&STDIN" or die $!;
( run in 0.864 second using v1.01-cache-2.11-cpan-5735350b133 )