On Wed, Apr 16, 2008 at 12:32 PM, Jörg Walter wrote:
> On Wednesday, 16. April 2008, Martijn wrote:
>
>> Just wondering if someone has written something that does session
>> management on AxKit2? Will need to do so, and will try to make it as
>> much like Apache::AxKit::Session as possible, but thought someone else
>> might have done that already.
>
> Not yet, AFAIK. Although I wrote (one of) the AxKit1 session module(s), I
> didn't port that to AxKit2 (which I use regularly). I use the inherent
> session-id capability of HTTP Digest authentication for identifying users.

So I went ahead and wrote something myself - see below. It is simple
and does nothing but storing sessions, but it does that quite well I
think. At least it should be a good example of how easy it is to write
plugins for AxKit.

I'd be happy to hear of any problems with and about improvements for
the plugin. In particular, I'm a bit worried about needing to store
the cookies in the xmlresponse hook, for I obviously want the plugin
to work not just on XML documents. However, the response hook doesn't
seem to be called (or at least not for XML documents), while the
response_sent hook is called too late for cookies to be sent to the
browser.

Martijn.

-------------8<--------------------8<--------------------

#!/usr/bin/perl -w

=head1 NAME

axkit_session - Plugin for simple session management within AxKit2

=head1 SYNOPSIS

 Plugin axkit_session

 # optionally:
 SessionLength 30
 SessionCacheNameSpace axkit_session
 SessionCookieName axkit_session

=head1 DESCRIPTION

This plugin creates a hash ref of session variables that is available
to any hook in any plugin by calling
 $self->client->notes("SESSION")

By default, the hash ref contains two L<DateTime> objects
C<session_started> and C<session_updated>, which contain the time when
the session was started and last updated respectively.

It currently only uses cookies; hence website visitors need to have
cookies enabled for sessions to work.

=head1 CONFIG

=head2 SessionLength integer

Length of the session in minutes (default 30).

=head2 SessionCacheNameSpace string

Sets the namespace of the session cache (default C<axkit_session>).

=head2 SessionCookieName string

Sets the name of the session cookie (default C<axkit_session>).

=cut

use DateTime;
use Cache::FileCache;

########################################################################
# initialization
########################################################################

sub conf_sessionlength;
sub conf_sessioncachenamespace;
sub conf_sessioncookiename;

########################################################################
# functions
########################################################################

sub _new_session {
       # starts a new session
       my $self = shift;

       my $cache = new Cache::FileCache ( { namespace =>
$self->config('sessioncachenamespace') || 'axkit_session' } );

       # generate the session ID - currently 16 random lowercase
alphabetic characters
       my $session_id = join('', map {chr} map {97 + rand(26)} (0..15));
       $self->client->notes('session_id',$session_id);

       # store the session hash ref in the global $_session hash
       $cache->set($session_id,$self->client->notes('SESSION'));

       $self->client->notes('SESSION',{});
       $self->client->notes('SESSION')->{session_started} = DateTime->now();
}

sub _continue_session {
       # continue with session
       my ($self,$session_id) = (shift,shift);

       my $cache = new Cache::FileCache ( { namespace =>
$self->config('sessioncachenamespace') || 'axkit_session' } );

       $self->client->notes('session_id',$session_id);
       $self->client->notes('SESSION',$cache->get($session_id));
       $self->client->notes('SESSION')->{session_started} ||= DateTime->now();
       $self->client->notes('SESSION')->{session_updated} = DateTime->now();
}

sub _store_session {
       # store the session in the cache
       my $self = shift;
       my $session_id = $self->client->notes('session_id');

       my $cache = new Cache::FileCache ( { namespace =>
$self->config('sessioncachenamespace') || 'axkit_session' } );

       $self->client->headers_out->cookie(
               ($self->config('sessioncookiename') || 'axkit_session') =>
$self->client->notes('session_id'),
               'max-age' => 60*($self->config('sessionlength') || 30),
               'path' => '/',
               'secure' => 0,
       );

       
$cache->set($session_id,$self->client->notes('SESSION'),($self->config('sessionlength')
|| '30').' minutes');
}

########################################################################
# hooks
########################################################################

sub hook_post_read_request {
       my $self = shift;

       my $cache = new Cache::FileCache ( { namespace =>
$self->config('sessioncachenamespace') || 'axkit_session' } );

       my $session_cookie =
$self->client->headers_in->cookie($self->config('sessioncookiename')
|| 'axkit_session');

       if (!$session_cookie || not defined $cache->get($session_cookie)) {
               $self->_new_session();
       } else {
               $self->_continue_session($session_cookie);
       }

       return DECLINED;
}

sub hook_xmlresponse {
       my $self = shift;

       $self->_store_session();
}

########################################################################
# the end :)
########################################################################

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to