Apache-Session

 view release on metacpan or  search on metacpan

lib/Apache/Session.pm  view on Meta::CPAN

#############################################################################
#
# Apache::Session
# Apache persistent user sessions
# Copyright(c) 1998, 1999, 2000, 2001, 2004 Jeffrey William Baker (jwbaker@acm.org)
# Distribute under the Perl License
#
#############################################################################

=head1 NAME

Apache::Session - A persistence framework for session data

=head1 SYNOPSIS

  use Apache::Session::MySQL;

  my %session;

  #make a fresh session for a first-time visitor
  tie %session, 'Apache::Session::MySQL';

  #stick some stuff in it
  $session{visa_number} = "1234 5678 9876 5432";

  #get the session id for later use
  my $id = $session{_session_id};

  #...time passes...

  #get the session data back out again during some other request
  my %session;
  tie %session, 'Apache::Session::MySQL', $id;

  validate($session{visa_number});

  #delete a session from the object store permanently
  tied(%session)->delete;


=head1 DESCRIPTION

Apache::Session is a persistence framework which is particularly useful
for tracking session data between httpd requests.  Apache::Session is
designed to work with Apache and mod_perl, but it should work under
CGI and other web servers, and it also works outside of a web server
altogether.

Apache::Session consists of five components: the interface, the object store,
the lock manager, the ID generator, and the serializer.  The interface is
defined in Session.pm, which is meant to be easily subclassed.  The object
store can be the filesystem, a Berkeley DB, a MySQL DB, an Oracle DB, a
Postgres DB, Sybase, or Informix. Locking is done by lock files, semaphores, or
the locking capabilities of the various databases.  Serialization is done via
Storable, and optionally ASCII-fied via MIME or pack().  ID numbers are
generated via MD5.  The reader is encouraged to extend these capabilities to
meet his own requirements.

A derived class of Apache::Session is used to tie together the three following
components.  The derived class inherits the interface from Apache::Session, and
specifies which store and locker classes to use.  Apache::Session::MySQL, for
instance, uses the MySQL storage class and also the MySQL locking class. You
can easily plug in your own object store or locker class.

=head1 INTERFACE

The interface to Apache::Session is very simple: tie a hash to the
desired class and use the hash as normal.  The constructor takes two
optional arguments.  The first argument is the desired session ID
number, or undef for a new session.  The second argument is a hash
of options that will be passed to the object store and locker classes.

=head2 tieing the session

Get a new session using DBI:

 tie %session, 'Apache::Session::MySQL', undef,
    { DataSource => 'dbi:mysql:sessions' };

Restore an old session from the database:

 tie %session, 'Apache::Session::MySQL', $session_id,
    { DataSource => 'dbi:mysql:sessions' };


=head2 Storing and retrieving data to and from the session

Hey, how much easier could it get?

 $session{first_name} = "Chuck";
 $session{an_array_ref} = [ $one, $two, $three ];
 $session{an_object} = Some::Class->new;

=head2 Reading the session ID

lib/Apache/Session.pm  view on Meta::CPAN


sub is_new          { $_[0]->{status} & NEW }
sub is_modified     { $_[0]->{status} & MODIFIED }
sub is_deleted      { $_[0]->{status} & DELETED }
sub is_synced       { $_[0]->{status} & SYNCED }

sub make_new        { $_[0]->{status} |= NEW }
sub make_modified   { $_[0]->{status} |= MODIFIED }
sub make_deleted    { $_[0]->{status} |= DELETED }
sub make_synced     { $_[0]->{status} |= SYNCED }

sub make_old        { $_[0]->{status} &= ($_[0]->{status} ^ NEW) }
sub make_unmodified { $_[0]->{status} &= ($_[0]->{status} ^ MODIFIED) }
sub make_undeleted  { $_[0]->{status} &= ($_[0]->{status} ^ DELETED) }
sub make_unsynced   { $_[0]->{status} &= ($_[0]->{status} ^ SYNCED) }



#Tie methods
#
#Here we are hiding our complex data persistence framework behind
#a simple hash.  See the perltie manpage.



sub TIEHASH {
    my $class = shift;
    
    my $session_id = shift;
    my $args       = shift || {};

    #Set-up the data structure and make it an object
    #of our class
    
    my $self = {
        args         => $args,
        data         => { _session_id => $session_id },
        serialized   => undef,
        lock         => 0,
        status       => 0,
        lock_manager => undef,  # These two are object refs ...
        object_store => undef,
        generate     => undef,  # but these three are subroutine refs
        serialize    => undef,
        unserialize  => undef,
    };
    
    bless $self, $class;

    $self->populate;


    #If a session ID was passed in, this is an old hash.
    #If not, it is a fresh one.

    if (defined $session_id  && $session_id) {
        
        #check the session ID for remote exploitation attempts
        #this will die() on suspicious session IDs.

        &{$self->{validate}}($self);
        
        if (exists $args->{Transaction} && $args->{Transaction}) {
            $self->acquire_write_lock;
        }
        
        $self->{status} &= ($self->{status} ^ NEW);
        $self->restore;
    }
    else {
        $self->{status} |= NEW;
        &{$self->{generate}}($self);
        $self->save;
    }
    
    return $self;
}

sub FETCH {
    my $self = shift;
    my $key  = shift;
        
    return $self->{data}->{$key};
}

sub STORE {
    my $self  = shift;
    my $key   = shift;
    my $value = shift;
    
    $self->{data}->{$key} = $value;
    
    $self->{status} |= MODIFIED;
    
    return $self->{data}->{$key};
}

sub DELETE {
    my $self = shift;
    my $key  = shift;
    
    $self->{status} |= MODIFIED;
    
    delete $self->{data}->{$key};
}

sub CLEAR {
    my $self = shift;

    $self->{status} |= MODIFIED;
    
    $self->{data} = {};
}

sub EXISTS {
    my $self = shift;
    my $key  = shift;
    
    return exists $self->{data}->{$key};
}



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