NAME
Apache::SessionManager - mod_perl session manager extension to manage sessions over HTTP requests
SYNOPSIS
In httpd.conf:
PerlModule Apache::SessionManager
PerlTransHandler Apache::SessionManager
<Location /my-app-with-session>
SetHandler perl-script
PerlHandler Apache::MyModule
PerlSetVar SessionManagerTracking On
PerlSetVar SessionManagerExpire 3600
PerlSetVar SessionManagerInactivity 900
PerlSetVar SessionManagerStore File
PerlSetVar SessionManagerStoreArgs "Directory => /tmp/apache_sessions"
</Location>
<Location /my-app-without-sessions>
PerlSetVar SessionManagerTracking Off
</Location>
DESCRIPTION
Apache::SessionManager is a mod_perl module that helps session management of a web application. This module is a wrapper around Apache::Session persistence framework for session data. It creates a session object and makes it available to all other handlers transparenlty by putting it in pnotes. In a mod_perl handlers you can retrieve the session object directly from pnotes with predefined key SESSION_MANAGER_HANDLE
:
my $session = $r->pnotes('SESSION_MANAGER_HANDLE') ? $r->pnotes('SESSION_MANAGER_HANDLE') : ();
then it is possible to set a value in current session with:
$$session{'key'} = $value;
# same as
$session->{'key'} = $value;
or it is possible to read value session with:
print "$$session{'key'}";
# same as
print $session->{'key'};
The following functions also are provided (but not yet exported) by this module:
- Apache::SessionManager::get_session(Apache->request)
-
Return an hash reference to current session object.
In a mod_perl module handler:
sub handler { my $r = shift; my $session = Apache::SessionManager::get_session($r); ... }
In a CGI Apache::Registry script:
my $session = Apache::SessionManager::get_session(Apache->request);
- Apache::SessionManager::destroy_session(Apache->request)
-
Destroy the current session object.
For instance this is a simple mod_perl handler:
package Apache::MyModule;
use strict;
use Apache::Constants qw(:common);
sub handler {
my $r = shift;
# retrieve session
my $session = Apache::SessionManager::get_session($r);
# set a value in current session
$$session{'key'} = "some value";
# same as
$session->{'key'} = "some value";
# read value session
print $$session{'key'};
# same as
print $session->{'key'};
# destroy session explicitly
Apache::SessionManager::destroy_session($r);
...
return OK;
}
and you can install it by adding this kind of lines in httpd.conf:
PerlModule Apache::SessionManager
PerlTransHandler Apache::SessionManager
<Location /mymodule>
SetHandler perl-script
PerlHandler Apache::MyModule
PerlSetVar SessionManagerTracking On
PerlSetVar SessionManagerExpire 3600
PerlSetVar SessionManagerInactivity 900
PerlSetVar SessionManagerStore File
PerlSetVar SessionManagerStoreArgs "Directory => /tmp/apache_sessions"
</Location>
INSTALLATION
In order to install and use this package you will need Perl version 5.005 or better.
Prerequisites:
mod_perl (of course) with the appropriate call-back hooks (PERL_TRANS=1 PERL_HEADER_PARSER=1)
CGI::Cookie
Apache::Cookie >= 0.33 (libapreq) is preferred but not required (CGI::Cookie will be used instead)
Apache::Session >= 0.53 is required
Installation as usual:
% perl Makefile.PL
% make
% make test
% su
Password: *******
% make install
CONFIGURATION
To enable session tracking with this module you could modify httpd.conf or .htaccess files
Configuring via httpd.conf
To enable session tracking with this module via httpd.conf (or any files included by the Include
directive) you must add the following lines:
PerlModule Apache::SessionManager
PerlTransHandler Apache::SessionManager
PerlSetVar SessionManagerTracking On
This will activate the session manager over each request. It is posibible to activate this module only in certain locations:
<Location /my-app-dir>
PerlSetVar SessionManagerTracking On
</Location>
Also, it is possible to deactivate session management explicitly:
<Location /my-app-dir-without>
PerlSetVar SessionManagerTracking Off
</Location>
If you want to control session management by directory, you cannot use PerlTransHandler
, but you must install the module in a phase where the mapping of URI->filename has been made. Generally Header parsing
phase is a good place:
PerlModule Apache::SessionManager
<Directory /usr/local/apache/htdocs/perl>
<FilesMatch "\.perl$">
SetHandler perl-script
PerlHandler Apache::Registry
PerlSendHeader On
PerlSetupEnv On
Options ExecCGI
PerlHeaderParserHandler Apache::SessionManager
PerlSetVar SessionManagerTracking On
PerlSetVar SessionManagerExpire 3600
PerlSetVar SessionManagerInactivity 900
PerlSetVar SessionManagerName REGISTRY_SESSIONID
PerlSetVar SessionManagerStore File
PerlSetVar SessionManagerStoreArgs "Directory => /tmp/apache_sessions"
</FilesMatch>
</Directory>
Configuring via .htaccess
In the case you don't have access to httpd.conf or you want work with .htaccess files only , you can put similar directives directly into an .htaccess file:
<FilesMatch "\.(cgi|pl)$">
PerlHeaderParserHandler Apache::SessionManager
PerlSetVar SessionManagerTracking On
PerlSetVar SessionManagerExpire 3600
PerlSetVar SessionManagerInactivity 900
PerlSetVar SessionManagerName PERLSESSIONID
PerlSetVar SessionManagerStore File
PerlSetVar SessionManagerStoreArgs "Directory => /tmp/apache_session"
PerlSetVar SessionManagerDebug 5
</FilesMatch>
The only difference is that you cannot use Location
directive (I used FilesMatch
) and you must install Apache::SessionManager in Header parsing
phase of Apache request instead of URI translation
phase.
Notes on using .htaccess instead of httpd.conf
In this cases it is necessary to install Apache::SessionManager in
Header parsing
phase and not intoURI translation
phase (in this phase, .htaccess hasn't yet been processed).Using .htaccess, it is possible to use only cookies for the session tracking.
See Apache::SessionManager::cookpod for more info about module configuration and use within thirdy part packages.
DIRECTIVES
You can control the behaviour of this module by configuring the following variables with PerlSetVar
directive in the httpd.conf.
SessionManagerTracking
On|Off-
This single directive enables session traking
PerlSetVar SessionManagerTracking On
It can be placed in server config, <VirtualHost>, <Directory>, <Location>, <File> and .htaccess context. The default value is
Off
. SessionManagerURITracking
On|Off-
This single directive enables session URI traking
PerlSetVar SessionManagerURITracking On
where the session ID is embedded in the URI. This is a possible cookieless solution to track session ID between browser and server. Please see
URI TRACKING NOTES
section below for more details. The default value isOff
. SessionManagerExpire
number-
This single directive defines global sessions expiration time (in seconds).
PerlSetVar SessionManagerExpire 900
If non set, the default value is
3600
seconds. An explicit '0' value means no expiration time and the session will die when the user will close the browser. The module put the user start session time in a special session key_session_start
. SessionManagerInactivity
number-
This single directive defines user inactivity sessions expiration time (in seconds).
PerlSetVar SessionManagerInactivity 900
If not specified no user inactivity expiration policies are applied. The module put the user timestamp in a special session key
_session_timestamp
. SessionManagerName
string-
This single directive defines session cookie name
PerlSetVar SessionManagerName PSESSID
The default value is
PERLSESSIONID
SessionManagerCookieArgs
-
With this directive you can provide optional arguments for cookie attributes setting. The arguments are passed as comma-separated list of name/value pairs. The only attributes accepted are:
Domain
Set the domain for the cookie.
Path
Set the path for the cookie.
Secure
Set the secure flag for the cookie.
Expire
Set expire time for the cookie.
For instance:
PerlSetVar SessionManagerCookieArgs "Path => /some-path, \ Domain => .yourdomain.com, \ Secure => 1"
Please see the documentation for Apache::Cookie or CGI::Cookie in order to see more cookie arguments details.
SessionManagerStore
datastore-
This single directive sets the session datastore used by Apache::Session framework
PerlSetVar SessionManagerStore File
The following datastore plugins are available with Apache::Session distribution:
File
Sessions are stored in file system
MySQL
Sessions are stored in MySQL database
Postgres
Sessions are stored in Postgres database
Sybase
Sessions are stored in Sybase database
Oracle
Sessions are stored in Oracle database
DB_File
Sessions are stored in DB files
In addition to datastore plugins shipped with Apache::Session, you can pass the modules you want to use as arguments to the store constructor. The Apache::Session::Whatever part is appended for you: you should not supply it. If you wish to use a module of your own making, you should make sure that it is available under the Apache::Session package namespace. For example:
PerlSetVar SessionManagerStore SharedMem
in order to use Apache::Session::SharedMem to store sessions in RAM (but you must install Apache::Session::SharedMem before!)
The default value is
File
. SessionManagerLock
Null|MySQL|Semaphore|File-
This single directive set lock manager for Apache::Session::Flex. The default value is
Null
. SessionManagerGenerate
MD5|ModUniqueId|ModUsertrack-
This single directive set session ID generator for Apache::Session::Flex. The default value is
MD5
. SessionManagerSerialize
Storable|Base64|UUEncode-
This single directive set serializer for Apache::Session::Flex. The default value is
Storable
. SessionManagerStoreArgs
-
With this directive you must provide whatever arguments are expected by the backing store and lock manager that you've chosen. The arguments are passed as comma-separated list of name/value pairs.
For instance if you use File for your datastore, you need to pass store and lock directories:
PerlSetVar SessionManagerStoreArgs "Directory => /tmp/apache_sessions, \ LockDirectory => /tmp/apache_sessions/lock"
If you use MySQL for your datastore, you need to pass database connection informations:
PerlSetVar SessionManagerStoreArgs "DataSource => dbi:mysql:sessions, \ UserName => user, \ Password => password"
Please see the documentation for store/lock modules in order to pass right arguments.
SessionManagerItemExclude
string|regex-
This single directive defines the exclusion string. For example:
PerlSetVar SessionManagerItemExclude exclude_string
All the HTTP requests containing the 'exclude_string' string will be declined. Also is possible to use regex:
PerlSetVar SessionManagerItemExclude "\.m.*$"
and all the request (URI) ending by ".mpeg", ".mpg" or ".mp3" will be declined.
If
SessionManagerItemExclude
isn't defined, the default value is:(\.gif|\.jpe?g|\.png|\.mpe?g|\.css|\.js|\.txt|\.mp3|\.wav|\.swf|\.avi|\.au|\.ra?m)$
Note If you want process each request, you can set
SessionManagerItemExclude
with:PerlSetVar SessionManagerItemExclude "^$"
SessionManagerSetEnv
On|Off-
This single directive set the
SESSION_MANAGER_SID
environment variable with the current (valid) session ID:PerlSetVar SessionManagerSetEnv On
It makes session ID available to CGI scripts for use in absolute links or redirects. The default value is
Off
.To retrieve the
SESSION_MANAGER_SID
environment variabile you can do, for instance:mod_perl
print $r->subprocess_env('SESSION_MANAGER_SID');
CGI
print $ENV{'SESSION_MANAGER_SID'};
Server Side Includes
<!--#echo var="SESSION_MANAGER_SID" -->
SessionManagerDebug
level-
This single directive set debug level.
PerlSetVar SessionManagerDebug 3
If greather than zero, debug informations will be print to STDERR. The default value is
0
(no debug information will be print). SessionManagerEnableModBackhand
On|Off-
This single directive enable 'experimental' mod_backhand sticky session load balancing support. Someone asked me this feature, so I've added it.
PerlSetVar SessionManagerEnableModBackhand On
A few words on mod_backhand. mod_backhand is a load balancing Apache module. mod_backhand can attempt to find a cookie in order to hex decodes the first 8 bytes of its content into an IPv4 style IP address. It will attempt to find this IP address in the list of candidates and if it is found it will make the server in question the only remaining candidate. This can be used to implement sticky user sessions -- where a given user will always be delivered to the same server once a session has been established. Simply turning on this directive, you add hex IP address in front to session_id. See mod_backhand docs for more details (http://www.backhand.org/mod_backhand).
The default value is
Off
.
URI TRACKING NOTES
There are some considerations and issues in order to use the session ID embedded in the URI. In fact, this is a possible cookieless solution to track session ID between browser and server.
If you enable session ID URI tracking you must place all the PerlSetVar
directives you need in server config context (that is outside of <Directory> or <Location> sections) otherwise the handler will not work for these requests. The reason of this is that the URI will be rewrite with session ID on the left and all <Location> that you've defined will match no longer.
Alternatively it is possible to use <LocationMatch> section. For instance:
PerlModule Apache::SessionManager
PerlTransHandler Apache::SessionManager
<LocationMatch "^/([0-9a-h]+/)?my-app-dir">
SetHandler perl-script
PerlHandler MyModule
PerlSetVar SessionManagerTracking On
PerlSetVar SessionManagerURITracking On
PerlSetVar SessionManagerStore File
PerlSetVar SessionManagerStoreArgs "Directory => /tmp/apache_sessions"
</LocationMatch>
to match also URI with embedded session ID.
Another issue is if you use a front-end/middle-end architecture with a reverse proxy front-end server in front (for static content) and a mod_perl enabled server in middle tier to serve dynamic contents. If you use Apache as reverse proxy it became impossible to set the ProxyPass directive either because it can be palced only in server config and/or <VirtualHost> context, either because it isn't support for regex to match session ID embedded in the URI.
In this case, you can use the proxy support available via the mod_rewrite
Apache module by putting in front-end server's httpd.conf:
ProxyPass /my-app-dir http://middle-end.server.com:9000/my-app-dir
ProxyPassReverse / http://middle-end.server.com:9000/
RewriteEngine On
RewriteRule (^/([0-9a-h]+/)?my-app-dir.*) http://middle-end.server.com:9000$1 [P,L]
Take careful to make all links to static content as non relative link (use "http://myhost.com/images/foo.gif" or "/images/foo.gif") or the rewrite engine will proxy these requests to mod_perl server.
TODO
Add an OO interface by subclassing Apache request object directly
Add the possibility of auto-switch session ID tracking from cookie to URI in cookieless situation. The code from Greg Cope session manager implementation could be integrated.
Add the query string param support (other than cookie and URI) to track session ID between browser and server.
Include into the distro the session cleanup script (the scripts I use for cleanup actually)
Embed the cleanup policies not in a extern scripts but in a register_cleanup method
Test, test ,test ;-)
AUTHORS
Enrico Sorcinelli <enrico@sorcinelli.it>
THANKS
A particular thanks to Greg Cope <gjjc@rubberplant.freeserve.co.uk> for freeing Apache::SessionManager namespace from his RFC (October 2000). His SessionManager project can be found at http://sourceforge.net/projects/sessionmanager
BUGS
This library has been tested by the author with Perl versions 5.005, 5.6.0 and 5.6.1 on different platforms: Linux 2.2 and 2.4, Solaris 2.6 and 2.7 and Windows 98.
Send bug reports and comments to: enrico@sorcinelli.it In each report please include the version module, the Perl version, the Apache, the mod_perl version and your SO. If the problem is browser dependent please include also browser name and version. Patches are welcome and I'll update the module if any problems will be found.
VERSION
Version 0.05
SEE ALSO
Apache::SessionManager::cookpod, Apache::Session, Apache::Session::Flex, Apache::Request, Apache::Cookie, CGI::Cookie, Apache, perl(1)
COPYRIGHT AND LICENSE
Copyright (C) 2001-2003 Enrico Sorcinelli. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.