I think it's safe to say that this code pretty much assumes that you're running under mod_perl. I don't think it'll work under CGI.
How to use in a mason component:
$m->session->{'your_key'} = 'your val';Here's the syntax highlighted version of my session wrapper. Click here to download the sourcecode.
# use this in your httpd.conf like thus: # PerlRequire mason_session.pl # PerlSetVar MasonRequestClass HTML::Mason::Request::WithSession # # This code was heavially based off MasonX::Request::WithApacheSession package HTML::Mason::Request::WithSession; $VERSION = '0.01'; # best practices use strict; use warnings; use HTML::Mason::ApacheHandler; # we are extending HTML::Mason::Request::ApacheHandler use base qw(HTML::Mason::Request::ApacheHandler); # Import a subroutine error( ) which throws an HTML::Mason::Exception object use HTML::Mason::Exceptions ( abbr => ['error'] ); use Apache; use Apache::Request; # Apache::Session stuff, and stuff to deal with cookies use Apache::Cookie; use Apache::Session::Flex; sub new { my $class = shift; $class->alter_superclass( $HTML::Mason::ApacheHandler::VERSION ? 'HTML::Mason::Request::ApacheHandler' : $HTML::Mason::CGIHandler::VERSION ? 'HTML::Mason::Request::CGI' : 'HTML::Mason::Request' ); # make ourselves a copy of our new superclass return $class->SUPER::new(@_); } sub exec { my $self = shift; my $r = Apache->request(); # set up the session $self->_make_session; my @result; if (wantarray) { @result = eval { $self->SUPER::exec(@_) }; } elsif ( defined wantarray ) { $result[0] = eval { $self->SUPER::exec(@_) }; } else { eval { $self->SUPER::exec(@_) }; } # copy this in case _save_session overwrites $@ my $e = $@; # save the session $self->_save_session; # we hit a problem, call Mason's overloaded die(). die $e if $e; return wantarray ? @result : defined wantarray ? $result[0] : undef; } sub _make_session { my $self = shift; my $r = Apache->request(); # subrequests get the parent request's session, no need to regenerate it or fetch it. if ( $self->is_subrequest ) { $self->{session} = $self->parent_request->session(); return; } # nab cookies my %cookies = Apache::Cookie->fetch; # figure out the session id -- existing cookie value, or unbaked cookie # value. The Apache:::Session::Generate::ModUsertrack is _broken_. # # This is the correct way to do it. Please see # http://www.xabean.com/code/mason_session # for a fixed generate() subroutine for # Apache::Session::Generate::ModUsertrack. # You can ignore this if you don't intend to use ModUsertrack. # # The gist of the bug is that the ModUsertrack module sets the *VALUE* of # the cookie in notes, not a fully qualified cookie string. You can't try to # parse "1.2.3.4.12341234" as a full-on cookie string :) # # Thankfully, when you pass in a session_id, the Apache::Session::Generate # stuff works. # ***** BE AWARE ***** # # This code assumes that there will *ALWAYS* be a defined $session_id # variable -- that's what Apache's ModUsertrack module does. # If you decide not to use ModUsertrack, this will not work correctly # and you will need to add an if() to check if $session_id is defined. # # ***** BE AWARE ***** my $session_id = exists $cookies{Apache} ? $cookies{Apache}->value : $r->notes('cookie'); # session object, will turn into a hashref later... my %session; # here's where we set up our session. # Throw whatever you want in here based off Apache::Session::Flex if ($session_id) { # try the existing session id eval { tie %session, 'Apache::Session::Flex', $session_id, { Store => 'File', # <-- change this Lock => 'File', # <-- change this Directory => '/tmp/sessions/data', # <-- change this LockDirectory => '/tmp/sessions/locks', # <-- change this Generate => 'ModUsertrack', # <-- change this Serialize => 'Storable' # <-- change this }; }; # Oops! that session id didn't previously exist, so lets make one. # Note that undef is passed in for the session_id -- # Apache::Session::Generate::ModUsertrack takes care of # setting up the correct session_id value if ($@) { tie %session, 'Apache::Session::Flex', undef, { Store => 'File', # <-- change this Lock => 'File', # <-- change this Directory => '/tmp/sessions/data', # <-- change this LockDirectory => '/tmp/sessions/locks', # <-- change this Generate => 'ModUsertrack', # <-- change this Serialize => 'Storable' # <-- change this }; } } # save the session hashref in the Mason Request object $self->{session} = \%session; } # internal accessor methods sub _save_session { my $self = shift; tied( %{ $self->{session} } )->save(); } sub _delete_session { my $self = shift; tied( %{ $self->{session} } )->delete(); } # publicsession accessor method sub session { $_[0]->{session} } 1;