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:
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). So,: 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. Cheers Dave P -- David Precious ("bigpresh") http://www.preshweb.co.uk/ "Programming is like sex. One mistake and you have to support it for the rest of your life". (Michael Sinz)