Any-Daemon-HTTP

 view release on metacpan or  search on metacpan

lib/Any/Daemon/FCGI/ClientConn.pm  view on Meta::CPAN

        }
        elsif($type eq 'PARAMS')
        {   if(length $$body) { $reqdata->{params} .= $$body }
            else { $reqdata->{params_complete} = 1 }
        }
        elsif($type eq 'STDIN')  # Not for Authorizer
        {   if(length $$body) { $reqdata->{stdin}  .= $$body }
            else { $reqdata->{stdin_complete} = 1 }
        }
        elsif($type eq 'DATA')   # Filter only
        {   if(length $$body) { $reqdata->{data}   .= $$body }
            else { $reqdata->{data_complete} = 1 }
        }

        last if $reqdata->{params_complete}
             && $reqdata->{stdin_complete}
             && $reqdata->{data_complete};
    }

    # We still have this record in $reqdata
    my $req_id = $reqdata->{request_id};
    delete $requests->{$req_id};

    my $enc_params = delete $reqdata->{params};
    my $p = $reqdata->{params} = eval { $self->_body2hash(\$enc_params) };
    if($@)
    {    notice __x"fcgi {id} params error: {err}", id => $req_id, err => $@;
         delete $requests->{$req_id};
         return $self->get_request;
    }

    my $expected_stdin = $p->{CONTENT_LENGTH} || 0;
    $expected_stdin == length $reqdata->{stdin}
        or error __x"fcgi {id} received {got} bytes on stdin, expected {need}"
             , id   => $req_id
             , got  => length $reqdata->{stdin}
             , need => $expected_stdin;

    my $expected_data = $p->{FCGI_DATA_LENGTH} || 0;
    $expected_data == length $reqdata->{data}
        or error __x"fcgi {id} received {got} bytes for data, expected {need}"
            , id   => $req_id
            , got  => length $reqdata->{data}
            , need => $expected_data;

    my $request     = Any::Daemon::FCGI::Request->new($reqdata);

    my $remote_ip   = $request->param('REMOTE_ADDR');
    my $remote_host = gethostbyaddr inet_aton($remote_ip), AF_INET;
    info __x"fcgi {id} request from {host}"
      , id   => $req_id
      , host => $remote_host || $remote_ip;

    $self->keep_connection
        or $self->socket->shutdown(SHUT_RD);

    $request;
}

sub send_response($;$)
{   my ($self, $response, $stderr) = @_;

    #XXX Net::Async::FastCGI::Request demonstrates how to catch stdout and
    #XXX stderr via ties.  We don't use that here: cleanly work with
    #XXX HTTP::Message objects... errors are logged locally.

    my $req_id = $response->request->request_id;

    # Simply "Status: " in front of the Response header will make the whole
    # message HTTP::Response into a valid CGI response.
    $self->_reply_record(STDOUT => $req_id
      , 'Status: '.$response->as_string(CRLF));
    $self->_reply_record(STDOUT => $req_id, '');

    if($stderr && length $$stderr)
    {   $self->_reply_record(STDERR => $req_id, $$stderr);
        $self->_reply_record(STDERR => $req_id, '');
    }

    $self->_fcgi_end_request(REQUEST_COMPLETE => $req_id);

    $self->keep_connection
        or $self->socket->shutdown(SHUT_WR);

    $self;
}

sub keep_connection()
{   my $self = shift;
    $self->{ADFC_keep_conn} || keys %{$self->{ADFC_requests}}
}

#### MANAGEMENT RECORDS
# have req_id==0

sub _management_record($$)
{   my ($self, $type, $body) = @_;
      $type eq 'GET_VALUES' ? $self->_fcgi_get_values($body)
    :                         $self->_fcgi_unknown($body);
}

# Request record FCGI_GET_VALUES may be used by the front-end server to
# collect back_end settings.  In Apache, you have to configure it manually.

sub _fcgi_get_values($)
{   my $self = shift;
    my %need = $self->_body2hash(shift);

    # The maximum number of concurrent transport connections this
    # application will accept.
    $need{FCGI_MAX_CONNS} = $self->{ADFC_max_conns}
        if exists $need{FCGI_MAX_CONNS};

    # The maximum number of concurrent requests this application will accept.
    $need{FCGI_MAX_REQS} = $self->{ADFC_max_reqs}
        if exists $need{FCGI_MAX_REQS};

    # "0" if this application does not multiplex connections (i.e. handle
    # concurrent requests over each connection), "1" otherwise.
    $need{FCGI_MPXS_CONNS} = 0
        if exists $need{FCGI_MPXS_CONNS};

    $self->_reply_record(GET_VALUES_RESULT => 0, $self->hash2body(\%need));
}

# Reply record FCGI_UNKNOWN_TYPE is designed for protocol upgrades: to 
# respond to unknown record types.

sub _fcgi_unknown($)
{   my ($self, $body) = @_;
    $self->_reply_record(UNKNOWN_TYPE => 0, '');
}

# Reply END_REQUEST is used for all ways to close a BEGIN_REQUEST session.
# It depends on the $status code which additionals fields were sent.



( run in 0.501 second using v1.01-cache-2.11-cpan-39bf76dae61 )