CGI-Session-ExpireSessions-1.13000755001750001750 012150573411 15220 5ustar00ronron000000000000CGI-Session-ExpireSessions-1.13/Makefile.PL000444001750001750 144112150573411 17327 0ustar00ronron000000000000use ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. WriteMakefile ( ($] ge '5.005') ? ( 'AUTHOR' => 'Ron Savage (ron@savage.net.au)', 'ABSTRACT' => 'Expires CGI::Session db-based and file-based sessions', ) : (), clean => { FILES => 'blib/* Makefile MANIFEST CGI-Session-ExpireSessions-*' }, dist => { COMPRESS => 'gzip', SUFFIX => 'gz' }, DISTNAME => 'CGI-Session-ExpireSessions', NAME => 'CGI::Session::ExpireSessions', LICENSE => 'artistic_2', PL_FILES => {}, PREREQ_PM => { Carp => 0, CGI::Session => 4.14, File::Spec => 0, Test::More => 0, # Test::Pod => 1.45, # Make it optional. See t/pod.t }, VERSION_FROM => 'lib/CGI/Session/ExpireSessions.pm', ); CGI-Session-ExpireSessions-1.13/README000444001750001750 334712150573411 16244 0ustar00ronron000000000000README file for CGI::Session::ExpireSessions. Warning: WinZip 8.1 and 9.0 both contain an 'accidental' bug which stops them recognizing POSIX-style directory structures in valid tar files. You are better off using a reliable tool such as InfoZip: ftp://ftp.info-zip.org/pub/infozip/ 1 Installing from a Unix-like distro ------------------------------------ shell>gunzip CGI-Session-ExpireSessions-1.03.tgz shell>tar mxvf CGI-Session-ExpireSessions-1.03.tar On Unix-like systems, assuming you have installed Module::Build V 0.25+: shell>perl Build.PL shell>./Build shell>./Build test shell>./Build install On MS Windows-like systems, assuming you have installed Module::Build V 0.25+: shell>perl Build.PL shell>perl Build shell>perl Build test shell>perl Build install Alternately, without Module::Build, you do this: Note: 'make' on MS Windows-like systems may be called 'nmake' or 'dmake'. shell>perl Makefile.PL shell>make shell>make test shell>su (for Unix-like systems) shell>make install shell>exit (for Unix-like systems) On all systems: Run ExpireSessions.pm through you favourite pod2html translator. If you are using my fancy-pom2.pl, with its 'default.css' file installed in /apache2/htdocs/css/, you'd do: shell>perl fancy-pom2.pl html -css ExpireSessions.pm > /apache2/htdocs/ExpireSessions.html or perhaps something like: shell>perl fancy-pom2.pl html -css ExpireSessions.pm > /perl/html/site/lib/CGI/Session/ExpireSessions.html 2 Installing from an ActiveState distro --------------------------------------- shell>unzip CGI-Session-ExpireSessions-1.03.zip shell>ppm install --location=. CGI-Session-ExpireSessions shell>del CGI-Session-ExpireSessions-1.03.ppd shell>del PPM-CGI-Session-ExpireSessions-1.03.tar.gz CGI-Session-ExpireSessions-1.13/META.json000444001750001750 220012150573411 16770 0ustar00ronron000000000000{ "abstract" : "Expires CGI::Session db-based and file-based sessions", "author" : [ "Ron Savage " ], "dynamic_config" : 1, "generated_by" : "Module::Build version 0.4003, CPAN::Meta::Converter version 2.120921", "license" : [ "artistic_2" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "CGI-Session-ExpireSessions", "prereqs" : { "build" : { "requires" : { "Test::More" : "0" } }, "configure" : { "requires" : { "Module::Build" : "0.38" } }, "runtime" : { "requires" : { "CGI::Session" : "4.14", "Carp" : "0", "File::Spec" : "0" } } }, "provides" : { "CGI::Session::ExpireSessions" : { "file" : "lib/CGI/Session/ExpireSessions.pm", "version" : "1.13" } }, "release_status" : "stable", "resources" : { "license" : [ "http://www.perlfoundation.org/artistic_license_2_0" ] }, "version" : "1.13" } CGI-Session-ExpireSessions-1.13/CHANGES000444001750001750 1235512150573411 16376 0ustar00ronron000000000000Revision history for Perl extension CGI::Session::ExpireSessions. 1.13 Mon May 27 15:57:00 2013 - Replace /usr/bin/perl with /usr/bin/env perl. - Replace common::sense with use strict and use warnings, to get uninit var warnings. - Rename test files from \d\d-*.t to *.t. - Clean up the POD so it passes tests. Specifically, '=item 1' becomes '=item o 1', and all other '=item' tokens are replaced by '=item o' to match. 1.12 Sun Feb 21 12:54:42 2010 - Remove text 'All rights reserved' (for Debian licensing). - Remove POD heads 'Required Modules' and 'Changes'. 1.11 Wed Feb 10 14:01:28 2010 - MANIFEST.SKIP updated to exclude MYMETA.yml. Add MYMETA.yml. 1.10 Fri Nov 13 13:20:00 2009 - Run dos2unix - Rename Changes.txt to CHANGES 1.09 Thu May 15 11:11:00 2008 - Delete V 1.08 from CPAN and upload V 1.09, hoping CPAN will index it properly this time. All this because some uses have logged a ticket (RT#35515) about not being able to use 'cpan' to install the module. They are right, I can't get 'cpan' to work either - Start shipping Changelog.ini 1.08 Mon Jun 12 11:32:00 2006 - Version 1.07 was never uploaded to CPAN. It was just available from my site, and was meant for testing the proposed callback mechanism in CGI::Session::find. That mechanism was changed before CGI::Session 4.14 was released, so my module's code now changes to match. Also, since CGI::Session has been patched so its sub find() no longer updates the session's access time, my module now uses atime instead of ctime when checking for expiry 1.07 Wed Apr 12 14:36:00 2006 - Add method expire_sessions() which uses CGI::Session V 4 method find() to find all sessions, and then expires sessions if appropriate. All this without evaling the contents of the session and which therefore resolves RT bug 16069 - Document the new method and the new parameters to new() - Add test t/03-delete-via-find.t to test the new code - Add examples/expire-set.pl to demonstrate and document further ways of using the new method - Make CGI::Session V 4.13 a prerequisite 1.06 Tue Apr 4 10:04:00 2006 - Add binmode after open in sub expire_file_sessions - Change "eval $session[0]" into "eval join('', @session)" to handle session data containing \n - Add a new test, t/new-line.t, to test session data containing \n - The problem with session data containing \n characters was reported via RT by m-uchino at yetipapa.com 1.05 Wed Oct 26 11:25:00 2005 - Untaint the data read in from the sessions table before eval-ing it. The problem, reported (with a code patch) by Dr RA Jones, was that the original code triggered an insecure dependency warning when running under -T, but only when using DBD::PgPP under MS Windows. The exact reason for this warning in this situation remains a mystery - Simplify code in new() to no longer check if caller is an object as per the new standard on such matters 1.04 Tue Nov 02 15:20:00 2004 - Note: All files referred to here match the CGI::Session file name format /cgisess_[0-9a-f]{32}/ - Fix the assumption in sub expire_file_sessions() that the program was being run in the temp directory, by adding the temp directory's name as a prefix to all file names. Original patch: Matthias Bl�sing - Fix sub expire_file_sessions() to delete files of size <= 5 bytes which are old enough. Files of size 0 are sometimes created by CGI::Session under unknown circumstances. As always, use new(delta => 123) to change the definition of 'old enough' - Fix verbose message for file session where it should have referred to $$D{'_SESSION_ID'} and not $$D{'id'}. The latter was a careless copy-and-paste from the database code - Ignore recent files whose size is <= 5 bytes - Change text of verbose messages from 'Time lapsed' to 'Time elapsed' - Add a security warning to the POD. Actually this comment is redundant, because you always read the POD, right? 1.03 Mon Jul 19 14:47:00 2004 - Change Makefile.PL to coexist with Module::Build - Add t/pod.t to test all PODs 1.02 Tue Jun 29 10:08:00 2004 - Add code so sessions which have already expired are also deleted. Originally, the module allowed you to force sessions to expire, via the delta parameter to new(). Now it also checks for sessions which have already expired, that is for sessions which CGI::Session would delete automatically when retrieving them. Thanx to Adam Gent for this suggestion - Rewrite the POD where it discusses expiration and deletion 1.01 Tue Apr 27 10:01:00 2004 - Add another parameter to new(): table_name. This allows you to store sessions in a table with a non-default name. The default name is of course 'sessions'. Thanx to Mark Stosberg for this suggestion - This module does not work with Mark's module CGI::Session::PureSQL. The best solution to this problem seems to be to extend CGI::Session to offer a session iterator. This suggesion is also from Mark. I will propose this today to the author of CGI::Session when I report the bug in CGI:Session V 3.94 line 168, which says: if ( $arg->isa('CGI') ) This bug means classes such as CGI::Simple can't be used here as a replacement for CGI. The code needs to be something like: if ($arg -> can('cookie') )... elsif ($arg -> can('param') )... 1.00 Mon Apr 19 12:37:29 2004 - Original version CGI-Session-ExpireSessions-1.13/Changelog.ini000444001750001750 1303712150573411 17771 0ustar00ronron000000000000[Module] Name=CGI::Session::ExpireSessions Changelog.Creator=Module::Metadata::Changes V 2.04 Changelog.Parser=Config::IniFiles V 2.78 [V 1.13] Date=2013-05-27T15:57:00 Comments= < 123) to change the definition of 'old enough' - Fix verbose message for file session where it should have referred to $$D{'_SESSION_ID'} and not $$D{'id'}. The latter was a careless copy-and-paste from the database code - Ignore recent files whose size is <= 5 bytes - Change text of verbose messages from 'Time lapsed' to 'Time elapsed' - Add a security warning to the POD. Actually this comment is redundant, because you always read the POD, right? EOT [V 1.03] Date=2004-07-19T14:47:00 Comments= <isa('CGI') ) This bug means classes such as CGI::Simple can't be used here as a replacement for CGI. The code needs to be something like: if ($arg -> can('cookie') )... elsif ($arg -> can('param') )... EOT [V 1.00] Date=2004-04-19T12:37:29 Comments=- Original version CGI-Session-ExpireSessions-1.13/Build.PL000444001750001750 101612150573411 16647 0ustar00ronron000000000000use Module::Build; Module::Build -> new ( module_name => 'CGI::Session::ExpireSessions', license => 'artistic_2', dist_abstract => 'Expires CGI::Session db-based and file-based sessions', dist_author => 'Ron Savage ', build_requires => { Test::More=> 0, # Test::Pod => 1.45, # Make it optional. See t/pod.t }, configure_requires => { Module::Build => 0.3800, }, requires => { Carp => 0, CGI::Session => 4.14, File::Spec => 0, }, ) -> create_build_script(); CGI-Session-ExpireSessions-1.13/META.yml000444001750001750 125212150573411 16626 0ustar00ronron000000000000--- abstract: 'Expires CGI::Session db-based and file-based sessions' author: - 'Ron Savage ' build_requires: Test::More: 0 configure_requires: Module::Build: 0.38 dynamic_config: 1 generated_by: 'Module::Build version 0.4003, CPAN::Meta::Converter version 2.120921' license: artistic_2 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: CGI-Session-ExpireSessions provides: CGI::Session::ExpireSessions: file: lib/CGI/Session/ExpireSessions.pm version: 1.13 requires: CGI::Session: 4.14 Carp: 0 File::Spec: 0 resources: license: http://www.perlfoundation.org/artistic_license_2_0 version: 1.13 CGI-Session-ExpireSessions-1.13/MANIFEST000444001750001750 35112150573411 16465 0ustar00ronron000000000000Build.PL Changelog.ini CHANGES examples/expire-sessions.pl examples/expire-set.pl lib/CGI/Session/ExpireSessions.pm Makefile.PL MANIFEST This list of files META.json META.yml README t/delete-via-find.t t/new-line.t t/pod.t t/use.t CGI-Session-ExpireSessions-1.13/t000755001750001750 012150573411 15463 5ustar00ronron000000000000CGI-Session-ExpireSessions-1.13/t/new-line.t000444001750001750 157312150573411 17531 0ustar00ronron000000000000#!/usr/bin/env perl use strict; use diagnostics; BEGIN { use Test::More; plan(tests => 5); use_ok('CGI::Session'); use_ok('CGI::Session::ExpireSessions'); }; # Create a block so $s goes out of scope before we try to access the session. # Without the {}, CGI::Session::ExpireSessions does not see this session, # although it will see sessions created by previous runs of this program. { my($s) = new CGI::Session(undef, undef, {Directory => 't'} ); ok($s, 'The test session has been created'); $s -> expire(1); ok($s -> id, "The test session's id has been set"); $s -> param(purpose => "Test new-line within session data. Works with CGI::Session::ExpireSessions V 1.06\n"); ok($s -> param('purpose'), "The test session's parameter called 'purpose' has been set"); } CGI::Session::ExpireSessions -> new(delta => 0, temp_dir => 't', verbose => 1) -> expire_file_sessions(); CGI-Session-ExpireSessions-1.13/t/pod.t000444001750001750 20412150573411 16543 0ustar00ronron000000000000use Test::More; eval "use Test::Pod 1.45"; plan skip_all => "Test::Pod 1.45 required for testing POD" if $@; all_pod_files_ok(); CGI-Session-ExpireSessions-1.13/t/delete-via-find.t000444001750001750 202712150573411 20743 0ustar00ronron000000000000#!/usr/bin/env perl use strict; use diagnostics; BEGIN { use CGI::Session; use CGI::Session::ExpireSessions; use Test::More; if (CGI::Session -> can('find') ) { plan tests => 3; } else { plan skip_all => "Requires a version of CGI::Session with method 'find()'"; } }; # Create a block so $s goes out of scope before we try to access the session. # Without the {}, CGI::Session::ExpireSessions does not see this session, # although it will see sessions created by previous runs of this program. { my($s) = new CGI::Session(undef, undef, {Directory => 't'} ); ok($s, 'The test session has been created'); $s -> expire(1); ok($s -> id, "The test session's id has been set"); #print "id: ", $s -> id(), ". \n"; $s -> param(purpose => "Create session simply to test deleting it with CGI::Session's sub find()"); ok($s -> param('purpose'), "The test session's parameter called 'purpose' has been set"); } CGI::Session::ExpireSessions -> new(delta => 0, dsn_args => {Directory => 't'}, verbose => 1) -> expire_sessions(); CGI-Session-ExpireSessions-1.13/t/use.t000444001750001750 15112150573411 16556 0ustar00ronron000000000000use Test::More tests => 1; # ------------------------ BEGIN{ use_ok('CGI::Session::ExpireSessions'); } CGI-Session-ExpireSessions-1.13/lib000755001750001750 012150573411 15766 5ustar00ronron000000000000CGI-Session-ExpireSessions-1.13/lib/CGI000755001750001750 012150573411 16370 5ustar00ronron000000000000CGI-Session-ExpireSessions-1.13/lib/CGI/Session000755001750001750 012150573411 20013 5ustar00ronron000000000000CGI-Session-ExpireSessions-1.13/lib/CGI/Session/ExpireSessions.pm000444001750001750 4124512150573411 23517 0ustar00ronron000000000000package CGI::Session::ExpireSessions; # Name: # CGI::Session::ExpireSessions. # # Documentation: # POD-style documentation is at the end. Extract it with pod2html.*. # # Reference: # Object Oriented Perl # Damian Conway # Manning # 1-884777-79-1 # P 114 # # Note: # o Tab = 4 spaces || die. # # Author: # Ron Savage # Home page: http://savage.net.au/index.html # # Licence: # Australian copyright (c) 2004 Ron Savage. # # All Programs of mine are 'OSI Certified Open Source Software'; # you can redistribute them and/or modify them under the terms of # The Artistic License, a copy of which is available at: # http://www.opensource.org/licenses/index.html use strict; use warnings; require 5.005_62; require Exporter; use Carp; use CGI::Session; use File::Spec; our @ISA = qw(Exporter); # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. # This allows declaration use CGI::Session::ExpireSessions ':all'; # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK # will save memory. our %EXPORT_TAGS = ( 'all' => [ qw( ) ] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw( ); our $VERSION = '1.13'; # ----------------------------------------------- # Preloaded methods go here. # ----------------------------------------------- # Encapsulated class data. { my(%_attr_data) = ( _cgi_session_dsn => undef, _dbh => '', _delta => 2 * 24 * 60 * 60, # Seconds. _dsn_args => undef, _table_name => 'sessions', _temp_dir => '/tmp', _time => time(), _verbose => 0, ); sub _check_expiry { my($self, $D) = @_; my($expired) = 0; my($time) = time(); if ( ($time - $$D{'_SESSION_ATIME'}) >= $$self{'_delta'}) { $expired = 1; print STDOUT "Delta time: $$self{'_delta'}. Time elapsed: ", $time - $$D{'_SESSION_ATIME'}, ". Expired?: $expired. \n" if ($$self{'_verbose'}); } if ($$D{'_SESSION_ETIME'} && ! $expired) { $expired = 1 if ($time >= ($$D{'_SESSION_ATIME'} + $$D{'_SESSION_ETIME'}) ); print STDOUT "Last access time: $$D{'_SESSION_ATIME'}. Expiration time: $$D{'_SESSION_ETIME'}. Time elapsed: ", $time - $$D{'_SESSION_ATIME'}, ". Expired?: $expired. \n" if ($$self{'_verbose'}); } $expired; } sub _default_for { my($self, $attr_name) = @_; $_attr_data{$attr_name}; } # Warning: The args hashref passed in to sub _purge() has /no/ connexion # with the $self hashref with belongs to the object instantiated by our client. # The client code did something like this to create an object: # my($expirer) = CGI::Session::ExpireSessions -> new(delta => 1); # and we, the object, i.e. $expirer, are in fact the server. sub _purge { my($session, $args) = @_; return if ($session -> is_empty() ); if ($session -> is_expired() || ($$args{'_time'} - $session -> atime() >= $$args{'_delta'}) ) { print STDOUT "Expiring id @{[$session -> id()]}. \n" if ($$args{'_verbose'}); $session -> delete(); $session -> flush(); } } sub _standard_keys { keys %_attr_data; } } # End of encapsulated class data. # ----------------------------------------------- sub expire_db_sessions { my($self, %arg) = @_; $self -> set(%arg) if (%arg); Carp::croak(__PACKAGE__ . ". You must specify a value for the parameter 'dbh'") if (! $$self{'_dbh'}); my($sth) = $$self{'_dbh'} -> prepare("select * from $$self{'_table_name'}"); $sth -> execute(); my($data, $D, @id, $untainted_data); while ($data = $sth -> fetchrow_hashref() ) { # Untaint the data the brute force way. ($untainted_data) = $$data{'a_session'} =~ /(.*)/; eval $untainted_data; push @id, $$data{'id'} if ($self -> _check_expiry($D) ); } for (@id) { print STDOUT "Expiring db id: $_. \n" if ($$self{'_verbose'}); $sth = $$self{'_dbh'} -> prepare("delete from $$self{'_table_name'} where id = ?"); $sth -> execute($_); $sth -> finish(); } if ( ($#id < 0) && $$self{'_verbose'}) { print STDOUT "No db ids are due to expire. \n"; } } # End of expire_db_sessions. # ----------------------------------------------- sub expire_file_sessions { my($self, %arg) = @_; $self -> set(%arg) if (%arg); Carp::croak(__PACKAGE__ . ". You must specify a value for the parameter 'temp_dir'") if (! $$self{'_temp_dir'}); opendir(INX, $$self{'_temp_dir'}) || Carp::croak("Can't opendir($$self{'_temp_dir'}): $!"); my(@file) = map{File::Spec -> catfile($$self{'_temp_dir'}, $_)} grep{/cgisess_[0-9a-f]{32}/} readdir(INX); closedir INX; my($count) = 0; my($time) = time(); my($file, @stat, $D); for my $file (@file) { @stat = stat($file); # Delete old, tiny files. if ( ( ($time - $stat[8]) >= $$self{'_delta'}) && ($stat[7] <= 5) ) { $count++; print STDOUT "Delta time: $$self{'_delta'}. Size: $stat[7] bytes. Time elapsed: ", $time - $stat[8], ". Expired?: 1. \n" if ($$self{'_verbose'}); unlink $file; next; } # Ignore new, tiny files. next if ($stat[7] <= 5); open(INX, $file) || Carp::croak("Can't open($file): $!"); binmode INX; my(@session) = ; close INX; # Pod/perlfunc.html#item_eval # This does not work: # eval{no warnings 'all'; $session[0]}; # This was when I used to say 'eval $session[0];', but that fails # when the session data contains \n characters. Hence the join. eval join('', @session); if ($@) { print STDOUT "Unable to parse contents of file: $file. \n" if ($$self{'_verbose'}); next; } if ($self -> _check_expiry($D) ) { $count++; print STDOUT "Expiring file id: $$D{'_SESSION_ID'}. \n" if ($$self{'_verbose'}); unlink $file; } } print STDOUT "No file ids are due to expire. \n" if ( ($count == 0) && $$self{'_verbose'}); } # End of expire_file_sessions. # ----------------------------------------------- sub expire_sessions { my($self, %arg) = @_; return if (! CGI::Session -> can('find') ); # Return the result of find, which is: # o Undef for failure # o 1 for success $self -> set(%arg) if (%arg); return CGI::Session -> find ( $$self{'_cgi_session_dsn'}, sub{_purge(@_, { # This hashref is a parameter for _purge(). _delta => $$self{'_delta'} || 0, # These 2 defaults are in case the user sets them to undef! _time => $$self{'_time'} || time(), # The defaults then stop Perl issuing warning messages about _verbose => $$self{'_verbose'}, # uninitialized variables during the call to sub _purge(). })}, $$self{'_dsn_args'} ); } # End of expire_sessions. # ----------------------------------------------- sub new { my($class, %arg) = @_; my($self) = bless({}, $class); for my $attr_name ($self -> _standard_keys() ) { my($arg_name) = $attr_name =~ /^_(.*)/; if (exists($arg{$arg_name}) ) { $$self{$attr_name} = $arg{$arg_name}; } else { $$self{$attr_name} = $self -> _default_for($attr_name); } } return $self; } # End of new. # ----------------------------------------------- sub set { my($self, %arg) = @_; for my $arg (keys %arg) { $$self{"_$arg"} = $arg{$arg} if (exists($$self{"_$arg"}) ); } } # End of set. # ----------------------------------------------- 1; __END__ =head1 NAME CGI::Session::ExpireSessions - Expires CGI::Session db-based and file-based sessions =head1 Synopsis #!/usr/bin/env perl use strict; use warnings; use CGI::Session::ExpireSessions; use DBI; # ----------------------------------------------- my($dbh) = DBI -> connect ( 'dbi:mysql:aussi:127.0.0.1', 'root', 'pass', { AutoCommit => 1, PrintError => 0, RaiseError => 1, ShowErrorStatement => 1, } ); CGI::Session::ExpireSessions -> new(dbh => $dbh, verbose => 1) -> expire_db_sessions(); CGI::Session::ExpireSessions -> new(temp_dir => '/tmp', verbose => 1) -> expire_file_sessions(); CGI::Session::ExpireSessions -> new(verbose => 1) -> expire_sessions(); # Note: You are strongly urged to use method expire_sessions() (it requires CGI::Session V 4 or later), # since it does not eval the session data, and hence avoids the security issues of evaling a string # which comes from outside the program. See examples/expire-set.pl, which contains extensive comments. =head1 Description C is a pure Perl module. It deletes C-type sessions which have passed their use-by date. It works with C-type sessions in a database or in disk files, but does not appear to work with C-type sessions. The recommended way to use this module is via method C, which requires C V 4 or later. Sessions can be expired under one of three conditions: =over 4 =item o You deem the session to be expired as of now =over 4 =item o Methods: C and C You want the session to be expired and hence deleted now because it's last access time is longer ago than the time you specify in the call to new, using the delta parameter. That is, delete the session because the time span, between the C time and now, is greater than delta. In other words, force sessions to expire. The module has always used this condition to delete sessions. =item o Method: C You want the session to be expired and hence deleted now because it's C time is longer ago than the time you specify in the call to new, using the delta parameter. =back =item o The session has already expired This section applies to all 3 methods: C, C and C. This condition is new as of V 1.02. You want the session to be deleted now because it has already expired. That is, you want this module to delete the session, rather than getting C to delete it, when C would delete the session automatically if you used C to retrieve the session. Note: This condition assumes the session's expiration time is defined (it does not have to be). =item o The file size is <= 5 bytes and was accessed more than 'delta' seconds ago This condition is new as of V 1.03. This section applies to method: C. See below for how to provide a value of delta to the constructor. Old versions of C sometimes create a file of size 0 bytes, so this test checks for such files, and deletes them if they are old enough. =back Sessions are deleted if any of these conditions is true. Sessions are deleted from the 'sessions' table in the database, or from the temp directory, depending on how you use C. =head1 Distributions This module is available both as a Unix-style distro (*.tgz) and an ActiveState-style distro (*.ppd). The latter is shipped in a *.zip file. See http://savage.net.au/Perl-modules.html for details. See http://savage.net.au/Perl-modules/html/installing-a-module.html for help on unpacking and installing each type of distro. =head1 Security For file-based sessions, method C parses the contents of the file, using eval{}, in an attempt to determine the access and expiration times recorded within the file. So, if you are uneasy about the security implication of this (as you should be), don't use this method. Use method C instead. The latter is a much more sophisticated way of expiring sessions, but it does require C V 4 or later. =head1 Constructor and initialization new(...) returns a C object. This is the class's contructor. Usage: CGI::Session::ExpireSessions -> new(). This method takes a set of parameters. Only some of these parameters are mandatory. For each parameter, call method C as new(param_1 => value_1, param_2 => value_2, ...). Note: As of V 1.07 of this module, you may call method C to set parameters after calling method C. Not only that, but you may pass into all of the 3 methods C, C and C any of the parameters accepted by C, since these 3 methods call C if their caller provides parameters. Parameters which can be used with C, C, or C: =over 4 =item o cgi_session_dsn This is the DSN (Data Source Name) used by C to control what type of sessions you previously created and what type of sessions you now wish to expire. Do not confuse this with the DSN used by C's method find(param_1, \&sub, {DataSource => other_dsn...}, ...) when referring to db-based sessions. Method C is the only method in this module which uses this parameter. So, when you call C, this parameter - cgi_session_dsn - determines the set of sessions processed by, and possibly expired by, the call to C. The default value is undef, which means C defaults to file-based sessions. This parameter is optional for file-based sessions, and mandatory for db-based sessions. =item o dbh This is a database handle for the database containing the table 'sessions'. Either this parameter is mandatory, or the temp_dir parameter is mandatory. =item o delta =over 4 =item o Methods: C and C This is the number of seconds since the C to the session, which determines whether or not the session will be expired. =item o Method: C This is the number of seconds since the C time of the session, which determines whether or not the session will be expired. =back The default value is 2 * 24 * 60 * 60, which is the number of seconds in 2 days. By default, then, sessions which were last accessed more than 2 days ago are expired. This parameter is optional. =item o dsn_args If your cgi_session_dsn uses file-based storage, then this hashref might contain keys such as: { Directory => Value 1, NoFlock => Value 2, UMask => Value 3 } If your cgi_session_dsn uses db-based storage, then this hashref contains (up to) 3 keys, and looks like: { DataSource => Value 1, User => Value 2, Password => Value 3 } These 3 form the DSN, username and password used by DBI to control access to your database server, and hence are only relevant when using db-based sessions. Method C is the only method in this module which uses the parameter dsn_args. The default value for this parameter is undef. These parameters are optional for file-based sessions, and mandatory for db-based sessions. =item o table_name This is the name of the database table used to hold the sessions. The default value is 'sessions'. This parameter is optional. =item o temp_dir This is the name of the temp directory where you store CGI::Session-type session files. The default value is '/tmp'. Either this parameter is mandatory, or the dbh parameter is mandatory. =item o time The session's C time is subtracted from the value of this parameter, and if the result is greater than or equal to the value of parameter 'delta', then the session is expired. Method C is the only method in this module which uses this parameter. The default value is obtained by calling time(). This parameter is optional. =item o verbose This is a integer, 0 or 1, which - when set to 1 - causes progress messages to be written to STDOUT. The default value is 0. This parameter is optional. =back =head1 Method: expire_db_sessions() Returns nothing. This method uses the dbh parameter passed to C to delete database-type sessions. =head1 Method: expire_file_sessions() Returns nothing. This method uses the temp_dir parameter passed to C to delete file-type sessions. =head1 Method: expire_sessions() Return value: =over 4 =item o undef Returns undef if your version of C does not support method C. Also, returns undef when C's method C failed for some reason. =item o 1 Returns 1 when C succeeds. =back Returns the result of calling CGI::Session's method find(), which will be undef for some sort of failure, and 1 for success. This method handles both file-based and db-based sessions. =head1 Example code See the examples/ directory in the distro. There are 2 demo programs: expire-sessions.pl and expire-set.pl. =head1 Author C was written by Ron Savage Iron@savage.net.auE> in 2004. Home page: http://savage.net.au/index.html =head1 Copyright Australian copyright (c) 2004, Ron Savage. All Programs of mine are 'OSI Certified Open Source Software'; you can redistribute them and/or modify them under the terms of The Artistic License, a copy of which is available at: http://www.opensource.org/licenses/index.html =cut CGI-Session-ExpireSessions-1.13/examples000755001750001750 012150573411 17036 5ustar00ronron000000000000CGI-Session-ExpireSessions-1.13/examples/expire-sessions.pl000444001750001750 77112150573411 22655 0ustar00ronron000000000000#!/usr/bin/env perl use strict; use warnings; use CGI::Session::ExpireSessions; use DBI; # ----------------------------------------------- my($dbh) = DBI -> connect ( 'DBI:mysql:aussi:127.0.0.1', 'root', 'pass', { AutoCommit => 1, PrintError => 0, RaiseError => 1, ShowErrorStatement => 1, } ); CGI::Session::ExpireSessions -> new(dbh => $dbh, verbose => 1) -> expire_db_sessions(); CGI::Session::ExpireSessions -> new(temp_dir => '/temp', verbose => 1) -> expire_file_sessions(); CGI-Session-ExpireSessions-1.13/examples/expire-set.pl000444001750001750 412012150573411 21612 0ustar00ronron000000000000#!/usr/bin/env perl # # Name: # expire-set.pl. # # Author: # Ron Savage # http://savage.net.au/index.html # # Purpose: # Call CGI::Session::ExpireSessions' sub expire_sessions() twice, # in order to demonstrate various options available with the module # CGI::Session::ExpireSessions. # # Note: # tab = 4 spaces || die. use strict; use warnings; use CGI::Session; use CGI::Session::ExpireSessions 1.08; # ------------- # Create a default (i.e. file-based) type of session, and then sleep so we can be sure # that the session will be older than the time specified by delta (1 second). # Also, you can - in the background - create a db-based session, and then # run this program, and that db-based session will be deleted by the first call to # sub expire_sessions(). my($s) = CGI::Session -> new(); sleep(2); # Note: # Parameters to CGI::Session::ExpireSessions can be given # when calling new() and/or when calling expire_sessions(). my($expirer) = CGI::Session::ExpireSessions -> new(delta => 1); # Note: # o cgi_session_dsn # This value is mandatory in order to use db-based sessions, since, by default, # CGI::Session used file-based sessions. # o dsn_args # This value (! undef) is mandatory, in order to use database sessions. $expirer -> expire_sessions ( cgi_session_dsn => 'driver:mysql;serializer:default;id:MD5', dsn_args => { DataSource => 'dbi:mysql:mids', User => 'root', Password => 'toor', } ); # Note: # o cgi_session_dsn # This value is mandatory to reset the value above back to the default. # Note that this default will be supplied by CGI::Session. # o dsn_args # This value (undef) is not really mandatory in order to cancel out the db_dsn above, # because the value of cgi_session_dsn is what says this call to expire_sessions() # is intended to deal with file-based sessions. Nevertheless, I set it to undef because # it would be /very confusing/ to specify database parametes to file-based sessions. # So don't do that! # o verbose # This value is optional. The default value is 0. $expirer -> expire_sessions ( cgi_session_dsn => undef, dsn_args => undef, verbose => 1, );