In response to delete session using CGI::Session I put together a snippet which uses CGI::Session to delete expired session files. It suffers from the unfortunate side effect that the last access time will be updated for un-expired sessions.

This new snippet below solves that problem by not using CGI::Session at all. However, it assumes that you're using the default serialization method and the default file naming scheme.

Note: it has been minimally tested on my part. It's probably not suitable for use in a production environment in its current state.

update, (10/09/2003): added "or die" to open. Fixed eval(). Tested w/ perl 5.8.0 on win2k.

use strict; use File::Find; use constant SESSION_DIR => '/temp/'; find( \&wanted, SESSION_DIR ); sub wanted { return unless /^cgisess_(.*)/; open( FILE, SESSION_DIR . $_ ) or die "Cannot open session $1: $!" +; my $data; { local $/; $data = <FILE>; } close( FILE ); my $D; eval( $data ); if ( time() >= $D->{ _SESSION_ETIME } + $D->{ _SESSION_ATIME } ) { unlink( SESSION_DIR . $_ ) or die "Cannot delete session $1: +$!"; print "$1\n"; } }

Replies are listed 'Best First'.
Re: Delete expired CGI::Session files
by Anonymous Monk on Oct 09, 2003 at 08:08 UTC
    thanks! very useful script... however I have do predeclare $D outside of the subroutine, else I get the error message in $@: "Global Symbol $D requires explicit package name at (eval 2)" (perl 5.6.1 on solaris)
Re: Delete expired CGI::Session files
by Anonymous Monk on Nov 12, 2003 at 18:08 UTC
    I don't understand how you get from newly declared $D to $D->{ _SESSION_ETIME }, etc. Can you explain what eval does in this case?

    my $D;
    eval( $data );

    if ( time() >= $D->{ _SESSION_ETIME } ...


    thanks

      Generaly, session files look something like this:

      $D = { "_SESSION_EXPIRE_LIST" => {}, "_SESSION_REMOTE_ADDR" => "127.0.0.1", "_SESSION_ATIME" => "1057334715", "_SESSION_CTIME" => "1057334688", "_SESSION_ID" => "2edc038f30ed95d3bd43f113b5385a5d", "_SESSION_ETIME" => undef };

      (Note, I've added some formatting. It's usually just one long line.)

      As you can see it's a dumped (see Data::Dumper) data structure. It starts off with an assignment to $D. When using strict you have to declare your variables. Thus my $D; before the eval.

      By eval()ing, I'm executing that code, thus doing the assignment to $D.

      Check this out:

      use strict; local $/; my $D; eval( <DATA> ); print $D->{ _SESSION_ID }; __DATA__ $D = { "_SESSION_EXPIRE_LIST" => {}, "_SESSION_REMOTE_ADDR" => "127.0.0.1", "_SESSION_ATIME" => "1057334715", "_SESSION_CTIME" => "1057334688", "_SESSION_ID" => "2edc038f30ed95d3bd43f113b5385a5d", "_SESSION_ETIME" => undef };

      Try commenting out my $D;. You'll get an error.

      HTH

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

        Crystal-clear now that I see the contents of a session file! Thanks