Apache2-ASP
view release on metacpan or search on metacpan
lib/Apache2/ASP/SessionStateManager.pm view on Meta::CPAN
package Apache2::ASP::SessionStateManager;
use strict;
use warnings 'all';
use base 'Ima::DBI';
use Digest::MD5 'md5_hex';
use Storable qw( freeze thaw );
use HTTP::Date qw( time2iso str2time );
use Scalar::Util 'weaken';
#==============================================================================
sub new
{
my ($class, %args) = @_;
my $s = bless {}, $class;
my $conn = $s->context->config->data_connections->session;
local $^W = 0;
__PACKAGE__->set_db('Main',
$conn->dsn,
$conn->username,
$conn->password
);
# Prepare our Session:
if( my $id = $s->parse_session_id() )
{
if( $s->verify_session_id( $id ) )
{
$s->{SessionID} = $id;
return $s->retrieve( $id );
}
else
{
$s->{SessionID} = $s->new_session_id();
$s->write_session_cookie();
return $s->create( $s->{SessionID} );
}# end if()
}
else
{
$s->{SessionID} = $s->new_session_id();
$s->write_session_cookie();
return $s->create( $s->{SessionID} );
}# end if()
}# end new()
#==============================================================================
sub context
{
$Apache2::ASP::HTTPContext::ClassName->current;
}# end context()
#==============================================================================
sub parse_session_id
{
my ($s) = @_;
my $cookiename = $s->context->config->data_connections->session->cookie_name;
no warnings 'uninitialized';
if( my ($id) = $ENV{HTTP_COOKIE} =~ m/$cookiename\=([a-f0-9]+)/ )
{
return $id;
}
elsif( ($id) = $s->context->r->headers_in->{Cookie} =~ m/$cookiename\=([a-f0-9]+)/ )
{
return $id;
}
else
{
return;
}# end if()
}# end parse_session_id()
#==============================================================================
# Returns true if the session exists and has not timed out:
sub verify_session_id
{
my ($s, $id) = @_;
my $range_start = time() - ( $s->context->config->data_connections->session->session_timeout * 60 );
local $s->db_Main->{AutoCommit} = 1;
my $sth = $s->db_Main->prepare_cached(<<"");
SELECT COUNT(*)
FROM asp_sessions
WHERE session_id = ?
AND modified_on BETWEEN ? AND ?
$sth->execute( $id, time2iso($range_start), time2iso() );
my ($active) = $sth->fetchrow();
$sth->finish();
return $active;
}# end verify_session_id()
#==============================================================================
sub create
{
my ($s, $id) = @_;
local $s->db_Main->{AutoCommit} = 1;
my $sth = $s->db_Main->prepare_cached(<<"");
INSERT INTO asp_sessions (
session_id,
session_data,
created_on,
modified_on
)
VALUES (
?, ?, ?, ?
)
my $now = time2iso();
no warnings 'uninitialized';
$s->{__signature} = md5_hex(
join ":",
map { "$_:$s->{$_}" }
grep { $_ ne '__signature' } sort keys(%$s)
);
my %clone = %$s;
$sth->execute(
$id,
freeze( \%clone ),
$now,
$now,
);
$sth->finish();
return $s->retrieve( $id );
}# end create()
#==============================================================================
sub retrieve
{
my ($s, $id) = @_;
local $s->db_Main->{AutoCommit} = 1;
my $sth = $s->db_Main->prepare_cached(<<"");
SELECT session_data, modified_on
FROM asp_sessions
WHERE session_id = ?
my $now = time2iso();
$sth->execute( $id );
my ($data, $modified_on) = $sth->fetchrow;
$data = thaw($data) || { SessionID => $id };
$sth->finish();
my $seconds_since_last_modified = time() - str2time($modified_on);
( run in 0.763 second using v1.01-cache-2.11-cpan-39bf76dae61 )