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 )