NAME
Apache::Session - Maintain session state across HTTP requests
SYNOPSIS
use Apache::Session::Win32; # use a global hash on Win32 systems
use Apache::Session::DBI; # use a database for real storage
use Apache::Session::File; # or maybe an NFS filesystem
use Apache::Session::ESP; # or use your own subclass
# Create a new unique session.
$session = Apache::Session::Win32->new($opts);
# fetch the session ID
$id = $session->id;
# open an old session, or undef if not defined
$session = Apache::Session::Win32->open($id,$opts);
# store data into the session (can be a simple
# scalar, or something more complex).
$session->{foo} = 'Hi!';
$session->{bar} = { complex => [ qw(list of settings) ] };
$session->store(); # write to storage
$session->unlock(); # always do this!
DESCRIPTION
This module provides the Apache/mod_perl user a mechanism for storing persistent user data in a global hash, which in independent of its real storage mechanism. Apache::Session provides an abstract baseclass from which storage classes can be derived. Existing classes include:
- Apache::Session::Win32
- Apache::Session::File
- Apache::Session::DBI /=These two are half-
- Apache::Session::IPC \=done, but broken. Hrmm
-
This package should be considered alpha, as the interface may change, and as it may not yet be fully functional. The docu- mentation and/or source codemay be erroneous. Use it at your own risk.
ENVIRONMENT
Apache::Session will respect the environment variables SESSION_SECRET, SESSION_LIFETIME, SESSION_ID_LENGTH, and SESSION_MAX_ATTEMPTS.
SESSION_SECRET is a secret string used to create MD5 hashes. The default value is "not very secret", and this can be changed in the source code.
SESSION_LIFETIME is the default lifetime of a session object in seconds. This value can be overridden by the calling program during session creation/retrieval. If the environment variable is not set, 3600 seconds is used.
SESSION_ID_LENGTH is the number if characters in the session ID. The default is 16.
SESSION_MAX_ATTEMPTS is the number of times that the package will attempt to create a new session. The package will choose a new random session ID for each attempt. The default value is 5, and should be set with regard to the type of real storage you will be using.
USAGE
Creating a new session object
$opts = { 'subclass-specific' => 'option overrides' };
$session = Apache::Session->new();
$session = Apache::Session->new( $opts );
$session = Apache::Session->new( { autocommit => 1 } );
Note that you must consult $session->{id} to learn the session ID for persisting it with the client. The new ID number is generated afresh, you are not allowed to specify it for a new object.
$opts, if provided, must be a hash reference.
Fetching a session object
$session = Apache::Session->open( $id );
$session = Apache::Session->open( $id, { autocommit => 1 , lifetime => 600} );
where $id is a session handle returned by a previous call to new(). You are free to use cookies, header munging, or extra-sensory perception to determine the session id to fetch.
The hashref of runtime options allows you to override the options that were used during the object creation. The standard options are "autocommit" and "lifetime", but your storage mechanism may define others.
Autocommit defines whether your session is update in real storage every time it is modified, or only when you call store(). If you set autocommit to 0 but don't call $session->store(), your changes will be lost.
Lifetime changes the current lifetime of the object.
Deleting a session object
$session->destroy();
Deletes the session from physical storage.
Committing changes
If you defined autocommit as false, you must do $session->store();
at the end of your script, or you will lose your changes.
Locking
Some storage methods, such as DBI, IPC, and File, require a
locking mechanism of some kind. Sessions are locked throughout
the duration of your script. The lock is obtained when the
session object is created (via new() or open()), and it cannot
be released automatically.
*** ALWAYS CALL UNLOCK() AT THE END OF YOUR PROGRAM ***
I wish there was a better way to do this, but there isn't(?) A
script using Apache::Session should always end this way, just to
be safe:
$session->store();
$session->unlock();
Data Methods
- $session->{variable_name} = <value>;
- $foo = $session->{variable_name};
- $foo = delete $session->{variable_name};
-
Hash-access is the preferred method for working with persistent session data. set(), read() and delete() are no longer supported as of 0.12.
Metadata
Metadata, such as the session ID, access time, lifetime, and expiration time are all stored in the session object. Therefore, the following hash keys are reserved and should not be assigned to:
_ID _EXPIRES _LIFETIME _ACCESSED _AUTOCOMMIT
These keys can be used to retrieve the desired information.
my $id = $session->{'_ID'};
But please don't do this:
$session->{'_ID'} = "Foo";
Other Methods
STORAGE CLASSES
Apache::Session::Win32
Uses a global hash to store sessions. Win32 does not listen to any special evironment variables.
Apache::Session::File
Stores each session in its own flat file. Files will be stored under the directory in $ENV{'SESSION_FILE_DIR'}. Without this environment variable, the package will die on startup.
Apache::Session::File uses a custom locking mechanism that should work regardless of whether the filesystem is local or networked. However, locks are not (currently) released when the session object is destroyed. If your program dies before it calls unlock(), the session will be lost. Comments and ideas on this problem are welcome.
Apache::Session::DBI and Apache::Session::IPC
These are not fully implemented. IPC is starting to annoy me.
SUBCLASSING
The Apache::Session module allows you to use the included Win32 implementation, but also makes it easy to subclass. Just ensure that your subclass includes each of the following functions:
- $class->fetch( $id )
-
Performs the very-basic physical fetch operation. This is used by open(), as well as by the base class's expire() routine, for the purpose of ensuring that the current session has not been deleted by the round of expire()s. Should return undef on failure.
- $class->open( $id [, \%options ] )
-
Fetches a pre-existing session from physical storage. You'll want to:
- ensure that $options is a hashref - fetch the session from physical storage by calling fetch(). e.g. my $session = $class->fetch($id); - set $self = $class->SUPER::open($session, $options ) - return $self or undef on failure.
The SUPER::open() will take care of merging your class's default Options() with the end-user's overrides, bless()ing the reference and tie()ing the hash in the proper way.
- create( $id [, \%options ] )
-
Creates a session, with the given id, in the physical storage. Create() should do some garbage collections, also. If a request is made to create an object with an ID which is already taken, create() should check to see whether the existing object is expired, and do the right thing. Create() should return undef on failure.
- Options( \%overrides )
-
Returns a hashref of options for your physical session storage, merging your class's default options with the end-user's overrides. If you wish, you may implement this like so:
sub Options { my( $class, $runtime_opts ) = @_; $class->SUPER::Options( $runtime_opts, { your => 'class', default => 'options', coded => 'here' } ); }
...and Apache::Session will do the work for you.
Ensure that your class has a default setting for autocommit, or you'll get a warning.
Apache::Session defines a single default setting, autocommit => 1, which may suit your needs fine. In this case, you don't have to override this method.
- $session->destroy()
-
Removes the session from the physical storage.
- $session->store()
-
Writes the session's persistent data to physical storage. This allows for a series of changes to be made to a session, followed by a commit() which stores those changes.
This function is called if $session->{'_AUTOCOMMIT'} is true, each time a value is stored into the session or removed from the session.
This function is duplicate in ->commit().
- $session->expire()
-
Ensures that the given session is not expired; removes the session from physical storage if the session is expired. Implementations may remove all expired sessions from storage, at the discretion of the implementor. Inside your implementation, returning $self->SUPER::expire() will check the storage to ensure that the current $self was not just deleted, and will return $self or undef as appropriate. $class->SUPER::expire will always return 1, in that there is no 'self' which might have been zapped from storage.
- $session->touch()
-
Updates the session's physical storage to reflect a new expiration time based on the current clock-tick plus the session lifetime.
- $session->lock()
-
Places a lock - in the physical storage - on the given session, ensuring that no other client to that physical storage may utilize the same session. Returns immediately if the lock can not be acheived.
- $session->unlock()
-
Removes the lock - in the physical storage - on the given session, allowing other clients to utilize that session.
MISC
BUGS
TODO
Create a TransHandler to translate out the session number from the URL and store it as the current session with the Apache request object as a note.
Create a current() method which will fetch the current session if it's valid.
Create a rewrite handler to translate outgoing HTML to include the current session number.
AUTHORS
Jeffrey Baker <jeff@godzilla.tamu.edu>, author and maintainer
Randy Harmon <rjharmon@uptimecomputers.com> created storage independence through subclassing, with useful comments, suggestions, and source code from:
Bavo De Ridder <bavo@ace.ulyssis.student.kuleuven.ac.be>
Jules Bean <jmlb2@hermes.cam.ac.uk>
Lincoln Stein <lstein@cshl.org>
Redistribute under the Perl Artistic License.
2 POD Errors
The following errors were encountered while parsing the POD:
- Around line 294:
'=item' outside of any '=over'
- Around line 308:
You forgot a '=back' before '=head1'