[Dancer-users] Custom Session Handler issues

David Precious davidp at preshweb.co.uk
Wed May 18 17:56:39 CEST 2011

On Wednesday 18 May 2011 16:37:31 J. Bobby Lopez wrote:
> I've been told (several IRC discussions, and scouring the Dancer docs) that
> unless I specifically enable sessions within dancer (either simple or
> YAML), that no session handling code gets initialized by default in
> Dancer.
> However I'm finding that something is preventing my CGI::Session files from
> being written to disk, as they are in my other non-dancer applications
> using code similar to the following:
> http://pastebin.jbldata.com/m2571aaf0

Looking at that code, you're initialising a session at initial runtime of the 
app, rather than within a route handler.

At runtime, there is no cookie for CGI.pm's cookie() to look at (I'm not even 
sure that using CGI.pm within a route handler would work, nor that trying to 
use CGI.pm within a Dancer app is advisable at all).


    my $sid = $query->cookie( 'CGISESSID' ) || undef;

$sid will be undef here.

    # Create / Load SESSION variables
    my $session_driver = "driver:File" if !defined( $sid );
    my $session = new CGI::Session( $session_driver, $sid,
                                { Directory => $session_dir_cache } );

What does CGI::Session do if you pass an undef session ID to the constructor?

Logic would assume that it will generate a session ID, but that might not be 
the case.

Also, you don't call $session->flush at any point to write the session 
contents to disc.

In theory, CGI::Session will implicitly flush the session when the $session 
object goes out of scope (which, in your example, will only be as the Dancer 
app exits); that isn't always reliable, however.

CGI::Session's own docs state:

"As a last resort, CGI::Session will automatically call flush for you just 
before the program terminates or session object goes out of scope. Automatic 
flushing has proven to be unreliable..."

> The code defines that the CGI::Session driver writes session files to
> '/tmp', however no session files are written there.  Running this app, you
> can clearly see that the custom session handler is working when you run the
> application from the command line (e.g, 'perl dancer-sessiontest.pl'), and
> visit the application in a browser using the '/' or '/dump_session' routes.

You're not seeing stuff being retrieved from the session; you're seeing the 
session object you created at runtime being used.  Different users accesssing 
that example app with different session ID cookies (or no session ID cookie at 
all) would get the same session's contents.

> Can anyone explain what is happening here, and how to get my session files
> handled correctly?

The correct answer I should give is of course "Use Dancer's own session 
support, which works", but I understand you're trying to maintain 
compatibility with other non-Dancer apps which use CGI::Session.

In that case, the proper answer is most likely to write a 
Dancer::Session::CGISession session engine which provides compatibility with 
CGI::Session-based sessions, then set that as your chosen session engine and 
use Dancer's own session support.

Writing a session engine wrapper is quite simple - you simply inherit from 
Dancer::Session::Abstract and implement the required methods.  You could take 
a look at Dancer::Session::Simple for a dead-simple example.


Dave P

David Precious  ("bigpresh")

   "Programming is like sex. One mistake and you have to support
   it for the rest of your life". (Michael Sinz)

More information about the Dancer-users mailing list