Jifty::Plugin::RequestInspector - Inspect requests


Jifty documentation Contained in the Jifty distribution.

Index


Code Index:

NAME

Top

Jifty::Plugin::RequestInspector - Inspect requests

DESCRIPTION

Top

Do not use this plugin directly. Other plugins use this plugin.

METHODS

Top

init

Sets up hooks into the request cycle.

before_request

Hooks into the request cycle to forward "request is beginning" and more metadata to RequestInspector plugins.

after_request

Hooks into the request cycle to forward "request is done" and more metadata to RequestInspector plugins.

clear_requests

Clears the list of request inspections.

add_request

Adds the current request inspection to the data store.

last_id

Returns the most recent request ID.

get_plugin_data RequestID, Plugin::Name

Returns the opaque plugin data for a particular request ID and plugin class name.

get_all_plugin_data Plugin::Name

Returns the opaque plugin data for all requests, for a given plugin class name.

get_request RequestID

Returns all data for a particular request ID.

requests

Returns a list of all inspections for all requests.

inspector_plugins

Returns a list of plugin instances that hook into RequestInspector.

new_request_inspection

Instantiates a new request inspection, setting up some default values.

should_handle_request CGI

Decides whether the request described by the CGI parameter should be handled, based on plugin configuration.

version

This plugin is versioned because it provides model classes.


Jifty documentation Contained in the Jifty distribution.

package Jifty::Plugin::RequestInspector;
use strict;
use warnings;
use base 'Jifty::Plugin';
use Time::HiRes 'time';

sub version { '0.0.2' }

__PACKAGE__->mk_accessors(qw(url_filter on_cookie persistent));

my $current_inspection;
my @requests;

sub init {
    my $self = shift;
    return if $self->_pre_init;

    my %opt = (
        url_filter => '.*',
        on_cookie  => undef,
        persistent => 0,
        @_
    );

    $self->url_filter(qr/$opt{url_filter}/);
    $self->on_cookie($opt{on_cookie});
    $self->persistent($opt{persistent});

    Jifty::Handler->add_trigger(before_request => sub {
        $self->before_request(@_);
    });

    Jifty::Handler->add_trigger(after_request => sub {
        $self->after_request(@_);
    });
}

sub requests {
    my $self = shift;
    my %args = (
        after => 0,
        @_,
    );

    if ($self->persistent) {
        my $requests = Jifty::Plugin::RequestInspector::Model::RequestCollection->new(
            current_user => Jifty->app_class('CurrentUser')->superuser
        );
        $requests->unlimit;
        $requests->limit( column => "id", operator => ">", value => $args{after}) if $args{after};
        return map { {%{$_->data}, id => $_->id} } @{$requests->items_array_ref};
    } else {
        return @requests[$args{after}..$#requests];
    }
}

sub get_request {
    my $self = shift;
    my $id   = shift;

    if ($self->persistent) {
        my $req = Jifty::Plugin::RequestInspector::Model::Request->new(
            current_user => Jifty->app_class('CurrentUser')->superuser
        );
        $req->load( $id );
        return undef unless $req->id;
        return { %{$req->data}, id => $req->id };
    } else {
        return $requests[$id - 1]; # 1-based
    }
}

sub add_request {
    my $self = shift;

    return unless $current_inspection;

    if ($self->persistent) {
        my $req = Jifty::Plugin::RequestInspector::Model::Request->new(
            current_user => Jifty->app_class('CurrentUser')->superuser
        );
        my ($ok, $msg) = $req->create(
            data => $current_inspection
        );
    } else {
        push @requests, $current_inspection;
        $requests[-1]{id} = scalar @requests;
    }
}

sub clear_requests {
    my $self = shift;

    if ($self->persistent) {
        Jifty->handle->simple_query( "DELETE FROM ".Jifty::Plugin::RequestInspector::Model::Request->table );
    } else {
        @requests = ();
    }
    undef $current_inspection;
}

sub last_id {
    my $self = shift;
    if ($self->persistent) {
        return Jifty->handle->fetch_result( "SELECT MAX(id) FROM ". Jifty::Plugin::RequestInspector::Model::Request->table );
    } else {
        return scalar @requests;
    }
}

sub get_plugin_data {
    my $self   = shift;
    my $id     = shift;
    my $plugin = shift;

    return $self->get_request($id)->{plugin_data}{$plugin};
}

sub get_all_plugin_data {
    my $self   = shift;
    my $plugin = shift;

    return map {$_->{plugin_data}{$plugin}} $self->requests;
}

sub new_request_inspection {
    my ($self, $req) = @_;

    my $ret = {
        start => time,
        url   => $req->request_uri,
    };

    if (my $cookie_name = $self->on_cookie) {
        $ret->{cookie} = $req->cookies->{$cookie_name};
    }
    return $ret;
}

do {
    my $inspector_plugins;
    sub inspector_plugins {
        if (!defined($inspector_plugins)) {
            $inspector_plugins = [
                grep {
                    $_->can('inspect_before_request') ||
                    $_->can('inspect_after_request')
                } Jifty->plugins
            ];
        }
        return @$inspector_plugins;
    }
};

sub before_request {
    my ($self, $handler, $req) = @_;

    return unless $self->should_handle_request($req);

    $current_inspection = $self->new_request_inspection($req);

    for my $plugin ($self->inspector_plugins) {
        next unless $plugin->can('inspect_before_request');
        my $plugin_data = $plugin->inspect_before_request($req);
        $current_inspection->{plugin_data}{ref $plugin} = $plugin_data;
    }
}

sub after_request {
    my ($self, $handler, $req) = @_;

    if ($current_inspection) {
        for my $plugin (reverse $self->inspector_plugins) {
            next unless $plugin->can('inspect_after_request');
            my $plugin_data = $current_inspection->{plugin_data}{ref $plugin};
            my $new_plugin_data =
              $plugin->inspect_after_request( $plugin_data, $req );
            if (defined($new_plugin_data)) {
                $current_inspection->{plugin_data}{ref $plugin} = $new_plugin_data;
            }
        }
        $current_inspection->{end} = time;
        $self->add_request;
    }

    undef $current_inspection;
}

sub should_handle_request {
    my $self = shift;
    my $req  = shift;

    my $url = $req->request_uri;
    return unless $url =~ $self->url_filter;

    if (my $cookie_name = $self->on_cookie) {
        return unless $req->cookies->{$cookie_name};
    }

    return 1;
}

1;

__END__