FusionInventory-Agent

 view release on metacpan or  search on metacpan

lib/FusionInventory/Agent/HTTP/Server/Inventory.pm  view on Meta::CPAN

    # Normalize no_compress
    $self->{no_compress} = $self->config('no_compress') !~ /^0|no$/i ? 1 : 0;
}

sub handle {
    my ($self, $client, $request, $clientIp) = @_;

    my $logger = $self->{logger};
    my $target = $self->{target};

    # rate limit by ip to avoid abuse
    if ($self->rate_limited($clientIp)) {
        $client->send_error(429); # Too Many Requests
        return 429;
    }

    if ($self->{request} eq 'apiversion') {
        my $response = HTTP::Response->new(
            200,
            'OK',
            HTTP::Headers->new( 'Content-Type' => 'text/plain' ),
            $VERSION
        );

        $client->send_response($response);

        return 200;
    }

    my $id = $request->header('X-Request-ID');

    unless ($id) {
        $self->info("No mandatory X-Request-ID header provided in $self->{request} request from $clientIp");
        $client->send_error(403, 'No session available');
        return 403;
    }

    my $remoteid = "{$id}\@[$clientIp]";

    my $session = $target->session(
        remoteid    => $remoteid,
        timeout     => $self->config('session_timeout'),
    );

    unless ($session) {
        $self->info("No session available for $remoteid");
        $client->send_error(403, 'No session available');
        return 403;
    }

    if ($self->{request} eq 'session') {

        my $nonce = $session->nonce();

        unless ($nonce) {
            $self->info("Session setup failure for $remoteid");
            $client->send_error(500, 'Session failure');
            return 500;
        }

        # Returned content is not useful but it should not be empty to support keep-alive
        # This is a LWP::UserAgent limitation
        my $response = HTTP::Response->new(
            200,
            'OK',
            HTTP::Headers->new( 'X-Auth-Nonce' => $nonce, 'Content-Type' => 'Plain/Text' ),
            "waiting inventory request..."
        );

        $client->send_response($response);

        return 200;
    }

    my $authorization = $session->authorized(
        token   => $self->config('token'),
        payload => $request->header('X-Auth-Payload') || ''
    );

    # Still cleanup the session
    $target->clean_session($remoteid);

    unless ($authorization) {
        $self->info("unauthorized remote inventory request for $remoteid");
        $client->send_error(403);
        return 403;
    }

    $self->debug("remote inventory request for $remoteid");

    my $agent = $self->{server}->{agent};

    my $task = FusionInventory::Agent::Task::Inventory->new(
        logger   => $logger,
        target   => $target,
        deviceid => $agent->{deviceid},
        datadir  => $agent->{datadir},
        config   => $agent->{config},
    );

    my $done;
    {
        local $SIG{CHLD} = sub {};
        $done = $task->run();
    }

    unless ($done) {
        $self->error("Failed to run inventory");
        $client->send_error(500, "Inventory failure");
        return 500;
    }

    my $data = $target->inventory_xml();
    my $content_type = 'application/xml';
    my @accept = split(/, */,$request->header('accept') || '');

    # check compression mode
    if (!$self->{no_compress} && Compress::Zlib->require() && grep { m|application/x-compress-zlib| } @accept) {
        # RFC 1950
        $content_type = 'application/x-compress-zlib';
        $self->debug('Using Compress::Zlib for compression');



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