tbone has asked for the wisdom of the Perl Monks concerning the following question:

I am attemtpting to use CGI::Application and CGI::Sessions. I am successful in creating and using my sessions, however the deletion of each session does not work as I had thought. I set an expiration time for each session of 5 min. If that window is idle for 5 minutes the session does expire and I am no longer able to read it, however the file still exists. Also, if I close the window the file still exists. Based on my reading of the docs, I thought that the expire function works like the delete function....or I could be missing something entirely. Here is my code
sub setup { my $self = shift; my $q = $self->query(); $self->start_mode('mode1'); $self->run_modes( 'mode1' => 'mode1', 'mode2' => 'mode2', 'mode3' => 'mode3'); $self->tmpl_path('template/'); my $session = new CGI::Session(undef, $q, {Directory=>"sessions"}) +; $session->expire('+5m'); my $session_id = $session->id(); $self->param('session' => $session); }

Replies are listed 'Best First'.
Re: delete session using CGI::Session
by shenme (Priest) on Oct 08, 2003 at 17:09 UTC
    Setting an expire time says when a session should expire.   However, it is only on the next attempted use of that same session id that new()/_init()/_init_old_session() look up the old session and decide whether to call delete()/flush() to really kill the file.   That much I can read from the code.   So perhaps my first sentence should read "Setting an expire time says when a session should become expired."   (note passive voice)

    I've traced through the module interactions with the Perl debugger on my system because I was seeing perhaps what you are seeing, that the session files are not being deleted.   They _do_ get deleted if referenced again.   (This on RH 7.2 w/ CGI::Session 3.95)   I still have lots of files leftover because some of my transactions are abandoned and the session id's are never referenced again.

    So, apart from abandoned transactions, are you sure you're setting the session id so that the next screen finds and references it?   In my program I accomplish this by using the $session->header() routine to set a cookie.   What are you using to get the session id back?

      I am using the cgi object in my creation of the session.
      sub setup{ my $self = shift; my $q = $self->query() #cgi object #code my $session = new CGI::Session(undef, $q, {Directory=>"sessions"}); $session->expire('+5m'); my $session_id = $session->id(); $self->param('session' => $session); }
      From the CGI::Session::Tutorial docs ...
      "If you pass an object, CGI::Session will try to retrieve the session id from either the cookie or query string and initialize the session accordingly. Name of the cookie and query string parameters are assumed to be CGISESSID by default."

      I am successful in retrieving a past session, but I'm still hung up on the expiration of the sessions. Again, I thought that after a session expires it deletes the file. You would believe that this should happen if either the time elapsed or the window was closed. However this does not happen. Any insight would be greatly appreciated
        I am successful in retrieving a past session, ...
        Are you sure?   CGI::Session will hand you back a session object every time, but it may be a newly created session.   I got myself so confused by this that I had to go find the $session->is_new() method just so I could tell.

        If you close the window but are using cookie's to 'remember' the session id then indeed the session id will be sent to the server when you re-invoke the CGI.   All should work.   Are you using cookie's?     (That was the meaning behind my mention of $session->header() above)

        Name of the cookie and query string parameters are assumed to be CGISESSID by default.
        If you are embedding the session id value in the query string, like so
            http://.../cgi-bin/test.pl?CGISESSID=1206ccd6ed4e985a6640b9943d419410
        
        then the session id value should get picked up by CGI.pm and found by CGI::Session and again all should be well.   Are you including the session id in any links from one page to another page?

        But as you mention CGI::Application you are likely using or planning to use forms.   You would need to embed the session id as a hidden value in one of your forms.   If you want CGI::Session to find it you would have to name the hidden field 'CGISESSID', as you mention.   You could "view source" from your browser to make sure you are actually getting this information into your form.

        They key to all this is knowing when the session id value is getting _back_ to your CGI for CGI::Session to find.   The more I look/test my own app the more I am convinced my leftover files are from abandoned transactions.   (I think the CGI::Session docs ought to mention the need for something like a cron job to clean up old left-over files every so often.)

        Abandoned sessions (e.g. a user session is created and the user never returns) will never be accessed again so the CGI::Session will never check to see if they have expired.

        The following code can be run from the command line and will delete expired session files (and will print out the IDs that have been deleted). NOTE: I've only minimally tested this on Win2k. You might want to perform some thorough testing before deploying this in a production environment.

        use strict; use File::Find; use CGI::Session; use constant SESSION_DIR => '/tmp/'; find( \&wanted, SESSION_DIR ); sub wanted { return unless /^cgisess_(.*)/; my $s = CGI::Session->new( undef, $1, { Directory => SESSION_DIR } + ); $s->delete && print "$1\n" if $s->is_new; }

        The code will look through all "cgisess" files, assuming they're stored in /tmp. If the session has expired it will be auto-deleted by CGI::Session. However, CGI::Session then creates a NEW session, so we have to delete it before we exit out or we'll just create a new file to replace the one we've deleted! CAVEAT: This code modifies the ATIME on un-expired sessions.

        --
        "To err is human, but to really foul things up you need a computer." --Paul Ehrlich

Re: delete session using CGI::Session
by jdtoronto (Prior) on Oct 08, 2003 at 16:49 UTC
    Search the monastery, there was another monk having similar problems within the last few months and he posted some working code.

    jdtoronto