in reply to delete session using CGI::Session

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?

Replies are listed 'Best First'.
Re: Re: delete session using CGI::Session
by tbone (Beadle) on Oct 08, 2003 at 17:26 UTC
    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

        Thanks for your code.   After seeing more than a couple files build up in my /tmp/ directory I went back to the docs and realized something.   The existing package is all about CGI and sessioning  (well, duh)  but has little for admin/debugging.   The caveat you mention is rather spooky and can't be avoided with the existing API.   It might be nice to have a 'peek' method that wouldn't affect anything to do with the 'state' of the session, such as time of last access.   (Sure wish I had some of that "free time" people keep mentioning...)