Plack
view release on metacpan or search on metacpan
lib/Plack/Handler/FCGI.pm view on Meta::CPAN
die "STDIN is not a socket: specify a listen location";
}
@{$self}{qw(stdin stdout stderr)}
= (IO::Handle->new, IO::Handle->new, IO::Handle->new);
my %env;
my $request = FCGI::Request(
$self->{stdin}, $self->{stdout}, $self->{stderr},
\%env, $sock,
($self->{nointr} ? 0 : &FCGI::FAIL_ACCEPT_ON_INTR),
);
my $proc_manager;
if ($self->{listen} or $running_on_server_starter) {
$self->daemon_fork if $self->{daemonize};
if ($self->{manager}) {
if (blessed $self->{manager}) {
for (qw(nproc pid proc_title)) {
die "Don't use '$_' when passing in a 'manager' object"
if $self->{$_};
}
$proc_manager = $self->{manager};
} else {
Plack::Util::load_class($self->{manager});
$proc_manager = $self->{manager}->new({
n_processes => $self->{nproc},
pid_fname => $self->{pid},
(exists $self->{proc_title}
? (pm_title => $self->{proc_title}) : ()),
});
}
# detach *before* the ProcManager inits
$self->daemon_detach if $self->{daemonize};
}
elsif ($self->{daemonize}) {
$self->daemon_detach;
}
} elsif (blessed $self->{manager}) {
$proc_manager = $self->{manager};
}
$proc_manager && $proc_manager->pm_manage;
while ($request->Accept >= 0) {
$proc_manager && $proc_manager->pm_pre_dispatch;
my $env = {
%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);
}
}
( run in 1.022 second using v1.01-cache-2.11-cpan-39bf76dae61 )