Apache::SessionManager::cookpod - Session management Cookpod with Apache::SessionManager
This HOWTO describes use of Apache::SessionManager with several application servers and toolkits available designed to run (also) under mod_perl. There are many ways to do it; this document will not describe all possible configurations.
Apache::SessionManager is a HTTP session manager wrapper around Apache::Session (Apache::Session provides a persistence mechanism for data associated with a session between a client and the server).
Apache::SessionManager allows you to integrate a transparent session management into your web application (it handles for you the cookie/URI session tracking management).
A session is a set of interactions (HTTP transactions). For example, a visitor may add items to be purchased to a shopping cart and the contents of the cart may be made visible by several different pages the visitor views during the purchase process.
This section describes how to use Apache::SessionManager within CGI::Application. The idea is to use sublass CGI::Application by adding session support and to use CGI::Application::SessionManager as base class for your applications.
CGI::Application is intended to make it easier to create sophisticated, reusable web-based applications.
CGI::Application is an Object-Oriented Perl module which implements an Abstract Class. It is not intended that this package be instantiated directly. Instead, it is intended that your Application Module will be implemented as a Sub-Class of CGI::Application.
This section illustrates how to use configure Apache::SessionManager for use within CGI::Application Perl extension.
In httpd.conf (or any files included by the Include directive):
Include
<IfModule mod_perl.c> PerlModule Apache::SessionManager PerlTransHandler Apache::SessionManager Alias /cgi-application "/usr/local/apache/cgi-application" <Location /cgi-application> SetHandler perl-script PerlHandler Apache::Registry PerlSendHeader On PerlSetupEnv On Options ExecCGI PerlSetVar SessionManagerTracking On PerlSetVar SessionManagerExpire 90 PerlSetVar SessionManagerInactivity 900 PerlSetVar SessionManagerName CGIAPPSESSIONID PerlSetVar SessionManagerStore File PerlSetVar SessionManagerStoreArgs "Directory => /tmp/apache_session_data/cgiapp" PerlSetVar SessionManagerDebug 5 </Location> </IfModule>
In the case you don't have access to httpd.conf, you can put similar directives directly into an .htaccess file:
<IfModule mod_perl.c> <FilesMatch "\.cgi$"> SetHandler perl-script PerlHandler Apache::Registry PerlSendHeader On PerlSetupEnv On Options ExecCGI PerlHeaderParserHandler Apache::SessionManager PerlSetVar SessionManagerTracking On PerlSetVar SessionManagerExpire 90 PerlSetVar SessionManagerInactivity 900 PerlSetVar SessionManagerName CGIAPPSESSIONID PerlSetVar SessionManagerStore File PerlSetVar SessionManagerStoreArgs "Directory => /tmp/apache_session_data/cgiapp" PerlSetVar SessionManagerDebug 5 </FilesMatch> </IfModule>
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.
Location
FilesMatch
Header parsing
URI translation
In this cases it is necessary to install Apache::SessionManager in Header parsing phase and not into URI translation phase (in this phase, .htaccess hasn't yet been processed).
Using .htaccess, it is possible to use only cookies for the session tracking.
We subclass CGI::Application in order to supply the cgiapp_init method where we restore the session object from datastore and put it into class property:
cgiapp_init
package CGI::Application::SessionManager; use Apache::SessionManager; use base 'CGI::Application'; sub cgiapp_init { my $self = shift; # if mod_perl $self->{'session'} = Apache::SessionManager::get_session(Apache->request) if $ENV{MOD_PERL}; }
Save it under the directory /usr/local/apache/cgi-application/CGI/Application/SessionManager.pm.
The reason to for subclassing this is the benefits is creating a custom "application super-class" from which which all your CGI applications would inherit, instead of CGI::Application.
Then we write WebApp.pm Application Module that inherit from our super-class CGI::Application::SessionManager:
package WebApp; use Data::Dumper; use base 'CGI::Application::SessionManager'; sub setup { my $self = shift; $self->start_mode('mode1'); $self->mode_param('rm'); $self->run_modes( 'mode1' => 'do_session' 'mode2' => 'do_stuff', 'mode3' => 'do_more_stuff', 'mode4' => 'do_something_else', ); } sub do_session { $self = shift; $self->{'session'}->{rand()} = rand; my $out = '<PRE>' . Dumper($self->{'session'}) . '<PRE>'; return $out; } sub do_stuff { return $_[0]->get_current_runmode() } sub do_more_stuff { return $_[0]->get_current_runmode() } sub do_something_else { print $_[0]->get_current_runmode() } 1;
Save it as /usr/local/apache/cgi-application/WebApp.pm.
To test our application we must implement the Instance Script that is what is actually called by your web server.
It is a very small, simple file which simply creates an instance of your application and calls an inherited method, run(). Following is the entirety of /usr/local/apache/cgi-application/webapp.cgi:
#!/usr/local/bin/perl use WebApp; my $webapp = WebApp->new(); $webapp->run();
Restart the httpd server and launch http://localhost/cgi-application/webapp.cgi
Apache::SessionManager, CGI::Application, Apache, perl
This section describes use of Apache::SessionManager with HTML::Mason (http://www.masonhq.com). There are many ways to do it; this document will not describe all possible configurations. It's meant to be a quick get on your feet HOWTO and also to answer some common questions that appear on the mailing list.
get on your feet
The idea is to use a global variable $session in order to store session object, and to initialize it into autohandler special component instead of call a separate component in each Mason page.
$session
HTML::Mason can be configured under mod_perl in two different ways:
This method is preferred because gives you complete control over how HTML::Mason handles requests at the cost of a bit of extra code to maintain.
In httpd.conf:
PerlModule Apache::SessionManager PerlTransHandler Apache::SessionManager PerlRequire /usr/local/apache/conf/masonhandler.pl Alias /mason "/usr/local/apache/htdocs/mason" <Location /mason> SetHandler perl-script PerlHandler HTML::Mason # Apache::SessionManager configuration (see 'perldoc Apache::SessionManager') PerlSetVar SessionManagerTracking On PerlSetVar SessionManagerExpire 3600 PerlSetVar SessionManagerInactivity 900 PerlSetVar SessionManagerName MASONSESSIONID PerlSetVar SessionManagerStore File PerlSetVar SessionManagerStoreArgs "Directory => /tmp/session_data/mason" </Location>
/usr/local/apache/conf/masonhandler.pl:
# # masonhandler.pl: HTML::Mason startup configuration Perl script # By Enrico Sorcinelli <enrico@sorcinelli.it> package HTML::Mason; use HTML::Mason; use HTML::Mason::ApacheHandler (args_method=>'mod_perl'); use strict; # List of all modules that will be used { package HTML::Mason::Commands; use DBI; use LWP; use Apache::SessionManager; ... } # Create Mason object my $ah = new HTML::Mason::ApacheHandler ( comp_root => '/usr/local/apache/htdocs/mason', data_dir => '/usr/local/apache/htdocs/mason/data', allow_globals => [ '$session' ] ); sub handler { my ($r) = @_; return $ah->handle_request($r); } 1;
In the case you don't have access to httpd.conf, you can put similar directive directly into an .htaccess file:
PerlRequire /usr/local/apache/conf/masonhandler.pl <FilesMatch "\.html$"> SetHandler perl-script PerlHandler HTML::Mason PerlHeaderParserHandler Apache::SessionManager PerlSetVar SessionManagerTracking On PerlSetVar SessionManagerExpire 3600 PerlSetVar SessionManagerInactivity 900 PerlSetVar SessionManagerName MASONSESSIONID PerlSetVar SessionManagerStore File PerlSetVar SessionManagerStoreArgs "Directory => /tmp/session_data/mason" PerlSetVar SessionManagerDebug 5 </FilesMatch>
Moreover, using .htaccess is less flexible and efficient because PerlRequire starts masonhandler.pl at run-time on each request.
PerlRequire
This is the easiest of the previous configuration. You must add a few PerlSetVar Mason* directives into Apache's configuration files.
PerlSetVar Mason*
This method is very easy to use and is appropriate for most uses of HTML::Mason .
PerlModule Apache::SessionManager PerlTransHandler Apache::SessionManager Alias /mason "/usr/local/apache/htdocs/mason" <Location /mason> SetHandler perl-script PerlHandler HTML::Mason::ApacheHandler PerlSetVar MasonCompRoot /usr/local/apache/htdocs/mason PerlSetVar MasonDataDir /usr/local/apache/htdocs/mason/data PerlSetVar MasonAllowGlobals $session PerlHeaderParserHandler Apache::SessionManager PerlSetVar SessionManagerTracking On PerlSetVar SessionManagerExpire 3600 PerlSetVar SessionManagerInactivity 900 PerlSetVar SessionManagerName MASONSESSIONID PerlSetVar SessionManagerStore File PerlSetVar SessionManagerStoreArgs "Directory => /tmp/session_data/mason" PerlSetVar SessionManagerDebug 5 </Location>
<FilesMatch "\.html$"> SetHandler perl-script PerlHandler HTML::Mason::ApacheHandler PerlSetVar MasonCompRoot /usr/local/apache/htdocs/mason PerlSetVar MasonDataDir /usr/local/apache/htdocs/mason/data PerlSetVar MasonAllowGlobals $session PerlHeaderParserHandler Apache::SessionManager PerlSetVar SessionManagerTracking On PerlSetVar SessionManagerExpire 3600 PerlSetVar SessionManagerInactivity 900 PerlSetVar SessionManagerName MASONSESSIONID PerlSetVar SessionManagerStore File PerlSetVar SessionManagerStoreArgs "Directory => /tmp/session_data/mason" PerlSetVar SessionManagerDebug 5 </FilesMatch>
In both cases it is necessary to install Apache::SessionManager in Header parsing phase and not into URI translation phase (in this phase, .htaccess hasn't yet been processed).
This is the autohandler /usr/local/apache/htdocs/mason/autohandler:
<%init> local $session = Apache::SessionManager::get_session($r); </%init> <% $m->call_next %>
Now, you you can use $session (hash reference) in all pages managed by HTML::Mason. For example this is /usr/local/apache/htdocs/mason/session.html:
<%perl> my $foo = 'bla bla'; $$session{'foo'} = $foo; # same as $session->{'foo'} = $foo; print $$session{'bar'}; </%perl>
HTML::Mason, Apache::Session, Apache::Session::Flex, Apache::SessionManager, Apache::Request, Apache::Cookie, Apache, perl(1)
This section describes use of Apache::SessionManager with PLP. PLP (http://plp.juerd.nl/) is yet another Perl embedder, primarily for HTML documents.
Unlike with other Perl embedders, there is no need to learn a meta-syntax or object model: one can just use the normal Perl constructs. PLP runs under mod_perl for speeds comparable to those of PHP, but can also be run as a CGI script. Note that the session management it is possible only under mod_perl environment.
The idea is to use a global variable $session in order to store session object, and to initialize it into start sub of PLP processor.
start
To do it, you must patch PLP.pm with following lines (you can find the patch also in patches/PLP-3.18.patch shipped with Apache::SessionManager distribution):
--- PLP.pm Fri Oct 18 21:47:07 2002 +++ PLP.pm-patched Fri May 30 11:38:37 2003 @@ -317,6 +317,13 @@ { package PLP::Script; use vars qw(%headers %header %cookies %cookie %get %post %fields); + + use vars qw($session); + eval { require Apache::SessionManager }; + unless ( $@ ) { + $session = Apache::SessionManager::get_session(Apache->request); + } + *headers = \%header; *cookies = \%cookie; PLP::Functions->import();
To apply the patch do (before installing PLP):
#> cd /path/to/src/PLP-3.18 #> patch -p0 < /path/to/PLP-3.18.patch
then you can continue installing PLP normally.
However you could use session management even without patching PLP.pm at the cost of a bit of extra code in your CGI scripts (see Testing Apache::SessionManager section).
Testing Apache::SessionManager
PerlModule Apache::SessionManager PerlTransHandler Apache::SessionManager Alias /plp "/usr/local/apache/htdocs/plp" <Location /plp> SetHandler perl-script PerlHandler PLP PerlSendHeader On PerlSetVar PLPcache On PerlSetVar SessionManagerTracking On PerlSetVar SessionManagerExpire 90 PerlSetVar SessionManagerInactivity 900 PerlSetVar SessionManagerName PLPSESSIONID PerlSetVar SessionManagerStore File PerlSetVar SessionManagerStoreArgs "Directory => /tmp/apache_session_data/plp" PerlSetVar SessionManagerDebug 5 </Location>
<FilesMatch "\.plp$"> SetHandler perl-script PerlHandler PLP PerlSendHeader On PerlSetVar PLPcache On PerlHeaderParserHandler Apache::SessionManager PerlSetVar SessionManagerTracking On PerlSetVar SessionManagerExpire 3600 PerlSetVar SessionManagerInactivity 900 PerlSetVar SessionManagerName PLPSESSIONID PerlSetVar SessionManagerStore File PerlSetVar SessionManagerStoreArgs "Directory => /tmp/apache_session_data/plp" PerlSetVar SessionManagerDebug 5 </FilesMatch>
Now you you can use $session (hash reference) in all pages managed by PLP. For example this is /usr/local/apache/htdocs/plp/session.plp:
<: my $title = 'Session management with PLP'; :> <HTML> <HEAD> <TITLE><: print $title :></TITLE> <BODY> <: use Data::Dumper; print "<H1>$title</H1>"; :> <B>Session dump</B><PRE> <: print Dumper($session); $session->{$$ . '-' . rand()} = rand; :> </PRE> </BODY> </HTML>
The previous example assumes that you've patched PLP.pm. Without the patch you must add the following line before using $session hash reference:
<: my $session = Apache::SessionManager::get_session(Apache->request); :>
PLP, Apache::Session, Apache::Session::Flex, Apache::SessionManager, Apache::Request, Apache::Cookie, Apache, perl(1)
This section describes how to use Apache::SessionManager with Template Toolkit (http://www.tt2.org). The idea is to use the Template::Plugin::Apache::SessionManager plugin (available on CPAN), the TT2 wrapper around Apache::SessionManager.
The Template Toolkit is a set of Perl modules which collectively implement a template processing system. In this context, a template is a text document containing special markup tags called 'directives'.
TT2 runs under mod_perl for speeds, but can also be run as a CGI script. Note that this session management is possible only under mod_perl environment.
This section illustrates how to use session manager TT2 plugin for use within Apache::Template mod_perl extension.
The Apache::Template module provides a simple interface to the Template Toolkit allowing Apache to serve directly TT2 files.
<IfModule mod_perl.c> PerlModule Apache::Template TT2Trim On TT2PostChomp On TT2EvalPerl On TT2Params uri env params TT2IncludePath /usr/local/apache/htdocs/tt2/includes TT2PreProcess config header TT2PostProcess footer PerlModule Apache::SessionManager PerlTransHandler Apache::SessionManager <LocationMatch "\.tt2$"> SetHandler perl-script PerlHandler Apache::Template PerlSetVar SessionManagerTracking On PerlSetVar SessionManagerExpire 600 PerlSetVar SessionManagerInactivity 60 PerlSetVar SessionManagerName TT2SESSIONID PerlSetVar SessionManagerDebug 5 PerlSetVar SessionManagerStore File PerlSetVar SessionManagerStoreArgs "Directory => /tmp/apache_session_data" </LocationMatch> </IfModule>
<IfModule mod_perl.c> PerlModule Apache::Template <FilesMatch "\.tt2$"> SetHandler perl-script PerlHandler Apache::Template PerlHeaderParserHandler Apache::SessionManager PerlSetVar SessionManagerTracking On PerlSetVar SessionManagerExpire 600 PerlSetVar SessionManagerInactivity 60 PerlSetVar SessionManagerName TT2SESSIONID PerlSetVar SessionManagerDebug 5 PerlSetVar SessionManagerStore File PerlSetVar SessionManagerStoreArgs "Directory => /tmp/apache_session_data" </FilesMatch> </IfModule>
Now you can use Template:Plugin::Apache::SessionManager plugin by 'USE' it in tt2 template file. This is a session.tt2 TT2 template:
Template:Plugin::Apache::SessionManager
[% USE my_sess = Apache.SessionManager %] <HTML> <HEAD> <TITLE>Session management with Apache::Template</TITLE> <BODY> The Session Dump [% USE dumper %] <PRE> [% dumper.dump(my_sess.session) %] </PRE> <H3>Getting session values</H3> Sigle session value<BR> ID is [% my_sess.get('_session_id') %]<P> Multiple session values<BR> [% FOREACH s = my_sess.get('_session_id','_session_timestamp') %] * [% s %]<BR> [% END %]<P> Multiple values by array ref<BR> [% keys = [ '_session_id', '_session_start' ]; FOREACH s = my_sess.get(keys) %] * [% s %]<BR> [% END %] All session values<BR> [% FOREACH s = my_sess.get %] * [% s %]<BR> [% END %] <H3>Setting session values:</H3> ID: [% my_sess.set('foo' => 10, 'bar' => 20, '_session_test' => 'test') %]<BR> </BODY> </HTML>
Save it under the root web directory and launch it with http://localhost/session.tt2
This is an example of deleting session keys and destroying session itself:
[% USE my_sess = Apache.SessionManager %] <HTML> <HEAD> <TITLE>Session management with Apache::Template</TITLE> <BODY> <PRE> [% USE dumper %] [% dumper.dump(my_sess.session) %] </PRE> <H3>Delete session values:</H3> [% my_sess.delete('foo','bar','_session_id') %]<BR> Delete session values by array ref: [% keys = ['foo','bar','_session_id']; my_sess.delete(keys) %]<BR> <H3>Destroy session</H3> [% my_sess.destroy %]<BR> </BODY> </HTML>
This section illustrates how to use session manager TT2 plugin for use in CGI scripts under Apache::Registry or Apache::PerlRun environment.
This example assumes that you can access to httpd.conf. If not, you must see the Notes on using .htaccess instead of httpd.conf on previous section about configuring it via .htaccess.
Notes on using .htaccess instead of httpd.conf
<IfModule mod_perl.c> Alias /perl/ /usr/local/apache/perl-scripts/ PerlModule Apache::SessionManager PerlTransHandler Apache::SessionManager <Location /perl> SetHandler perl-script PerlHandler Apache::Registry PerlSendHeader On PerlSetupEnv On Options ExecCGI PerlSetVar SessionManagerTracking On PerlSetVar SessionManagerExpire 600 PerlSetVar SessionManagerInactivity 60 PerlSetVar SessionManagerName TT2SESSIONID PerlSetVar SessionManagerDebug 5 PerlSetVar SessionManagerStore File PerlSetVar SessionManagerStoreArgs "Directory => /tmp/apache_session_data" </Location> </IfModule>
This is the simple CGI script session.cgi:
#!/usr/bin/perl use strict; use Template; my $file = 'session.tt2'; my $vars = { title => "Session management in a CGI Apache::Registry environment\n" }; my $template = Template->new(); $template->process($file, $vars) || die "Template process failed: ", $template->error(), "\n";
and this is a session.tt2 TT2 template (it's the same than the Apache::Template version!)
[% USE my_sess = Apache.SessionManager %] <HTML> <HEAD> <TITLE>[% title %]</TITLE> <BODY> The session dump [% USE dumper %] <PRE> [% dumper.dump(my_sess.session) %] </PRE> <H3>Getting session values</H3> Sigle session value<BR> ID is [% my_sess.get('_session_id') %]<P> Multiple session values<BR> [% FOREACH s = my_sess.get('_session_id','_session_timestamp') %] * [% s %]<BR> [% END %]<P> Multiple values by array ref<BR> [% keys = [ '_session_id', '_session_start' ]; FOREACH s = my_sess.get(keys) %] * [% s %]<BR> [% END %] All session values<BR> [% FOREACH s = my_sess.get %] * [% s %]<BR> [% END %] <H3>Setting session values:</H3> ID: [% my_sess.set('foo' => 10, 'bar' => 20, '_session_test' => 'test') %]<BR> </BODY> </HTML>
Save both into the /usr/local/apache/perl-scripts directory and launch http://localhost/perl/session.cgi
Apache::SessionManager, Template Toolkit, Apache, perl(1)
This section describes using Apache::SessionManager with simple authentication mechanism. There are many ways to do it; this document will not describe all possible configurations.
The idea is to write a custom authentication handler in order to verify each request that session is valid (the user has been already authenticaded).
PerlModule Apache::SessionManager PerlTransHandler Apache::SessionManager <Location /protected> PerlSetVar SessionManagerTracking On PerlSetVar SessionManagerExpire 3600 PerlSetVar SessionManagerInactivity 1800 PerlSetVar SessionManagerName SESSIONID PerlSetVar SessionManagerStore File PerlSetVar SessionManagerStoreArgs "Directory => /tmp/apache_session_data/" <Perl> use lib '/usr/local/apache/perl/'; </Perl> PerlAuthenHandler Apache::MyAuth AuthName "Reserved Club" AuthType Basic require valid-user PerlSetVar MyAuthLogin /protected/login.html </Location>
We have added a PerlSetvar directive in order to set MyAuthLogin variable with login form URI.
PerlSetvar
MyAuthLogin
PerlModule Apache::SessionManager <FilesMatch "\.foo$"> PerlHeaderParserHandler Apache::SessionManager PerlSetVar SessionManagerTracking On PerlSetVar SessionManagerExpire 3600 PerlSetVar SessionManagerInactivity 1800 PerlSetVar SessionManagerName SESSIONID PerlSetVar SessionManagerStore File PerlSetVar SessionManagerStoreArgs "Directory => /tmp/apache_session_data/" <Perl> use lib '/usr/local/apache/perl/'; </Perl> PerlAuthenHandler Apache::MyAuth AuthName "Reserved Club" AuthType Basic require valid-user PerlSetVar MyAuthLogin /protected/login.html </FilesMatch>
This simple code is the authentication handler /usr/local/apache/perl/Apache/MyAyth.pm:
package Apache::MyAuth; use Apache::Constants qw(:common REDIRECT); use Apache::SessionManager; use strict; sub handler { my $r = shift; my $session = Apache::SessionManager::get_session($r); # Login ok: user is already logged or login form is requested if ( $session->{'logged'} == 1 || $r->uri eq $r->dir_config('MyAuthLogin') ) { return OK; } # user not logged in or session expired # store in session the destination url if not set $session->{'redirect'} ||= $r->uri . ( ( $r->args ) ? ('?' . $r->args) : '' ); # verify credenitals unless ( verifiy_cred( ($r->args) ) ) { # Log error $r->log_error('MyAuth: access to ' . $r->uri . ' failed for ' . $r->get_remote_host); # Redirect to login page $r->custom_response(FORBIDDEN, $r->dir_config('MyAuthLogin')); return FORBIDDEN; } $session->{'logged'} = 1; # Redirect to original protected resource $r->content_type('text/html'); $r->header_out( Location => $session->{'redirect'} ); return REDIRECT; } # Check correct username and password with your own policies sub verifiy_cred { my %cred = @_; return 1 if ( $cred{'username'} eq 'foo' && $cred{'password'} eq 'baz' ); return 0; } 1;
Now we write an essential login form code /usr/local/apache/htdocs/protected/login.html (save it according to PerlSetVar MyAuthLogin setting):
PerlSetVar MyAuthLogin
<HTML> <BODY> <FORM METHOD="GET"> <INPUT TYPE="test" NAME="username" SIZE="10"> <INPUT TYPE="password" NAME="password" SIZE="10"> <INPUT TYPE="submit" VALUE="Login"> </FORM> </BODY> </HTML>
The recently released version of Microsoft's Internet Explorer (from 5.x) has some new "features" (?) which may affect sites.
The first new "feature" is that MSIE 5 may replace a site's own error messages with its in-built error pages. This occurs if the error page from the site is less than a particular size.
For most errors, this is 512 bytes. If the error page from the site is more than 512 bytes, MSIE 5 will display the site's error message, otherwise it will not display it.
For a few statuses (403, 405 and 410), the cut-off size is 256. The solution to this problem is to ensure that all error pages are greater than 512 bytes.
However note that most of Apache's built in error messages will be less than 512 bytes, so the only way to ensure that viewers see the site's real error pages is to use the ErrorDocument directive in Apache.
So, because we redefine FORBIDDEN response (status 403) with the HTML form, in order to work with MSIE, we must ensure to put more than 512 bytes into login.html file!
FORBIDDEN
Now, you you can test authentication mechanism by accessing some resources under protected area. In our case launch: http://localhost/protected/foo.html.
Note that the authorization can be applied also on dinamic contents (for example mod_perl handlers, CGI, etc) simply by setting right content handler in protected Locations.
This section illustrates how to use module without any system administrator account (usually root) in a machine.
root
Generally, this means that you cannot:
install modules in standard directories
configure httpd.conf Apache
There are several situations like this:
students on a departmental Web server at a university
individual customers of an ISP
clients of a Web-hosting company.
This chapter will helps you to use Apache::SessionManager in one of this situation.
There are some prerequisites in order to install and use Apache::SessionManager without root privileges:
a shell
Obvious
gcc
gcc is necessary in order to compile some required module like Storable or Digest::MD5 that have several XS code
make
Again, obvious
mod_perl with hook PERL_HEADER_PARSER=1
PERL_HEADER_PARSER=1
You can use this simple script (supplied in 'Practical mod_perl' book) to see enabled hooks:
use mod_perl_hooks; for my $hook(mod_perl::hooks()) { if (mod_perl::hooks($hook)) { print "$hook is enabled\n"; } else { print "$hook is not enabled\n"; } }
a configurable .htaccess file
I know, you could install and run another httpd instance on a port greather than 1024 and configure directly your httpd.conf. Then you could ask to your Webmaster in order to proxy your Apache from main web server (at port 80), if you dont want export to the world a web site in a port different than 80.
httpd
So, working with .htaccess files is the only possibilty to enable and configure session manager transparently (both for web users and your sysadmin).
Depending on wich Apache directives you would override, first you must check the status of AllowOverride directive for your directories.
AllowOverride
If none of AllowOverride directive appears in main httpd.conf then you can use all allowed directives in .htaccess file (by default AllowOverride is set to All, that means that any directive which has the .htaccess Context is allowed in .htaccess files).
All
Context
Otherwise, be sure that at least the directive like:
AllowOverride FileInfo
is present in order to use SetHandler in .htaccess file.
SetHandler
You can found more info about allowed directives at http://httpd.apache.org/docs/mod/core.html#allowoverride
For example, if you want to run CGI scripts also outside cgi-bin script directory, then a directive like:
AllowOverride FileInfo Options
should be appear in order to override directory behaviour by adding a:
Options +ExecCGI
in your .htaccess file.
lwp || ftp || ...
A way to transfer the perl packages in the system :-)
First of all, you must choose and create the directory that will contain the private installation copy of Perl modules. It should be readable by web server.
%> mkdir /path/to/your/perl-lib
As Apache::Session documentation says, "no particular modules are required, but most of Apache::Session's functions require Digest::MD5 and Storable".
Here, we explain how to install Storable if it isn't already present in the machine. Note that starting from Perl 5.8.0, Storable is a core module.
%> lwp-download http://search.cpan.org/CPAN/authors/id/A/AM/AMS/Storable-2.07.tar.gz %> tar -xzvf Storable-2.07.tar.gz %> cd Storable-2.07 %> perl Makefile.PL PREFIX=/path/to/your/perl-lib %> make %> make test %> make install
The installation procedure for Digest::MD5 or Apache::Cookie (libapreq) is almost the same.
%> lwp-download http://search.cpan.org/CPAN/authors/id/J/JB/JBAKER/Apache-Session-1.54.tar.gz %> tar -xzvf Apache-Session-1.54.tar.gz %> cd Apache-Session-1.54 %> perl Makefile.PL PREFIX=/path/to/your/perl-lib %> PERL5LIB=/path/to/your/perl-lib/lib make test %> make install
Plese note that the environment variable PERL5LIB setting is necessary before run tests in order to append /path/to/your/perl-lib/lib to @INC.
PERL5LIB
@INC
%> lwp-download http://search.cpan.org/CPAN/authors/id/E/EN/ENRYS/Apache-SessionManager-0.06.tar.gz %> tar -xzvf Apache-SessionManager-0.06.tar.gz %> cd Apache-SessionManager-0.06 %> PERL5LIB=/path/to/your/perl-lib/lib/site_perl:/path/to/your/perl-lib/lib \ perl Makefile.PL PREFIX=/path/to/your/perl-lib %> make %> PERL5LIB=/path/to/your/perl-lib/lib/site_perl:/path/to/your/perl-lib/lib \ make test %> make install
To test the installation:
%> PERL5LIB=/path/to/your/perl-lib/lib/site_perl perldoc Apache::SessionManager
Tipically, without system administration account you cannot manage Apache httpd.conf.
Also if you cannot install (or run) another httpd instance even at high ports (for example > 1024) the only possibilty to use session manager is to configure .htaccess file appropriately.
Using .htaccess, you must install Apache::SessionManager in Header parsing phase of Apache request instead of URI translation phase. Moreover, it is possible to use only cookies for the session tracking.
This is an example of how configure .htaccess file for use session (using file system as backend datastore) with CGI scripts under Apache::Registry:
<IfModule mod_perl.c> <Perl> use lib '/path/to/your/perl-lib/lib/site_perl', '/path/to/your/perl-lib/lib/'; # for Storable.pm </Perl> PerlModule Apache::SessionManager <FilesMatch "\.cgi$"> SetHandler perl-script PerlHandler Apache::Registry PerlSendHeader On PerlSetupEnv On Options ExecCGI PerlHeaderParserHandler Apache::SessionManager PerlSetVar SessionManagerTracking On PerlSetVar SessionManagerExpire 300 PerlSetVar SessionManagerInactivity 1800 PerlSetVar SessionManagerName SESSIONID PerlSetVar SessionManagerStore File PerlSetVar SessionManagerStoreArgs "Directory => /path/to/session/data" PerlSetVar SessionManagerDebug 5 </FilesMatch> </IfModule>
To test session you can use this simple CGI script:
#!/usr/bin/perl use Data::Dumper (); my $session = Apache::SessionManager::get_session(Apache->request); $session->{$$ . '-' . rand()} = rand; print "Content-type: text/html\n\n"; print '<PRE>' . Data::Dumper::Dumper($session) . '</PRE>';
Save it with a .cgi extension (like session.cgi) in the same directory where you have .htaccess and make it executable by web server.
This section describes how to use Apache::SessionManager with Apache::DBI when using a RDBMS for sessions back-end datastore.
Apache::DBI is a useful mod_perl module that caches database connections according to args (like DBD driver, user, password) and attributes. So, if your application uses a different user and/or attributes to connect to a (different) database, every connection will be cached. Also, every child could have these cached DB's handles. Apache::DBI works very well for web applications that uses same DB user.
There is no need of extra configuration steps to use advantage of persistent DB connections offered by Apache::DBI when using Apache::SessionManager with a RDBMS as session datastore.
Apache::DBI overrides DBI connect and disconnect methods and it intercepts, transparently, all related calls (including Apache::SessionManager DBI calls) by returning cached connections, if any.
connect
disconnect
Simply add a line like:
PerlModule Apache::DBI
in your httpd.conf, or:
use Apache::DBI;
in a startup.pl file where you can also setup your initial persistent connection.
However, remember that you must load Apache::DBI module before DBI or any module that uses it!
Restart the server and... test your application :-)
Additionally, you can enable perl-status console by putting, before loading Apache::DBI, lines like:
<Location /perl-status> SetHandler perl-script PerlHandler Apache::Status # or PerlResponseHandler Apache::Status in mod_perl 2 </Location>
You will see in the 'DBI connections' page, the cached datasource (in current child) used by Apache::Session::* plugin datastore you've chosen. Also yo can start httpd in single mode with -X option to work with a single child.
-X
Apache::DBI
This section describes how to move expiration policies on the client side by setting expiration cookie properties appropriately.
Practically, you must only add Expires cookie attribute in SessionManagerCookieArgs module directive:
Expires
SessionManagerCookieArgs
<Location /sessions> SetHandler perl-script PerlHandler Apache::MyModule PerlSetVar SessionManagerExpire none PerlSetVar SessionManagerStore File PerlSetVar SessionManagerCookieArgs "Path => /sessions, Expires => +2d" PerlSetVar SessionManagerStoreArgs "Directory => /tmp" </Location>
Optionally, you can set SessionManagerExpire with value none(or no or disable) in order to disable expiration session control at server side.
SessionManagerExpire
none
no
disable
However, it is not completely safe to left session expiration policies only on the client side. A SessionManagerExpire value should be always defined.
Apache::SessionManager,Apache::Request, Apache::Cookie, Apache, perl(1)
Enrico Sorcinelli <enrico@sorcinelli.it>
0.05
Send bug reports and comments to: enrico@sorcinelli.it In each report please include the module version, the Perl version, the Apache, the mod_perl version and your OS. If the problem is browser dependent please include also browser name and version.
Patches are welcome and I'll update the document if any problems or errors will be found.
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.
To install Apache::SessionManager, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Apache::SessionManager
CPAN shell
perl -MCPAN -e shell install Apache::SessionManager
For more information on module installation, please visit the detailed CPAN module installation guide.