prep meta data for release
[catagits/Catalyst-Plugin-Session.git] / lib / Catalyst / Plugin / Session.pm
index 9d65185..d6a6b9a 100644 (file)
@@ -14,7 +14,7 @@ use List::Util qw/ max /;
 
 use namespace::clean -except => 'meta';
 
-our $VERSION = '0.37';
+our $VERSION = '0.40';
 $VERSION = eval $VERSION;
 
 my @session_data_accessors; # used in delete_session
@@ -34,6 +34,7 @@ __PACKAGE__->mk_accessors(
           _tried_loading_session_data
           _tried_loading_session_expires
           _tried_loading_flash_data
+          _needs_early_session_finalization
           /
 );
 
@@ -111,6 +112,7 @@ sub finalize_headers {
     # up to date. First call to session_expires will extend the expiry, subs
     # just return the previously extended value.
     $c->session_expires;
+    $c->finalize_session if $c->_needs_early_session_finalization;
 
     return $c->maybe::next::method(@_);
 }
@@ -121,7 +123,8 @@ sub finalize_body {
     # We have to finalize our session *before* $c->engine->finalize_xxx is called,
     # because we do not want to send the HTTP response before the session is stored/committed to
     # the session database (or whatever Session::Store you use).
-    $c->finalize_session;
+    $c->finalize_session unless $c->_needs_early_session_finalization;
+    $c->_clear_session_instance_data;
 
     return $c->maybe::next::method(@_);
 }
@@ -135,7 +138,27 @@ sub finalize_session {
     $c->_save_session;
     $c->_save_flash;
 
-    $c->_clear_session_instance_data;
+}
+
+sub _session_updated {
+    my $c = shift;
+
+    if ( my $session_data = $c->_session ) {
+
+        no warnings 'uninitialized';
+        if ( Object::Signature::signature($session_data) ne
+            $c->_session_data_sig )
+        {
+            return $session_data;
+        } else {
+            return;
+        }
+
+    } else {
+
+        return;
+
+    }
 }
 
 sub _save_session_id {
@@ -150,35 +173,26 @@ sub _save_session_expires {
 
     if ( defined($c->_session_expires) ) {
 
-        my $threshold = $c->_session_plugin_config->{expiry_threshold} || 0;
-
-        if ( my $sid = $c->sessionid ) {
-            my $cutoff = $c->_get_stored_session_expires - $threshold;
-
-            if (!$threshold || $cutoff <= time) {
-                my $expires = $c->session_expires; # force extension
-                $c->store_session_data( "expires:$sid" => $expires );
+        if (my $sid = $c->sessionid) {
 
+            my $current  = $c->_get_stored_session_expires;
+            my $extended = $c->session_expires;
+            if ($extended > $current) {
+                $c->store_session_data( "expires:$sid" => $extended );
             }
 
         }
-
     }
 }
 
 sub _save_session {
     my $c = shift;
 
-    if ( my $session_data = $c->_session ) {
+    if ( my $session_data = $c->_session_updated ) {
 
-        no warnings 'uninitialized';
-        if ( Object::Signature::signature($session_data) ne
-            $c->_session_data_sig )
-        {
-            $session_data->{__updated} = time();
-            my $sid = $c->sessionid;
-            $c->store_session_data( "session:$sid" => $session_data );
-        }
+        $session_data->{__updated} = time();
+        my $sid = $c->sessionid;
+        $c->store_session_data( "session:$sid" => $session_data );
     }
 }
 
@@ -373,9 +387,32 @@ sub session_expires {
 
 sub extend_session_expires {
     my ( $c, $expires ) = @_;
-    $c->_extended_session_expires( my $updated = $c->calculate_initial_session_expires() );
-    $c->extend_session_id( $c->sessionid, $updated );
-    return $updated;
+
+    my $threshold = $c->_session_plugin_config->{expiry_threshold} || 0;
+
+    if ( my $sid = $c->sessionid ) {
+        my $expires = $c->_get_stored_session_expires;
+        my $cutoff  = $expires - $threshold;
+
+        if (!$threshold || $cutoff <= time || $c->_session_updated) {
+
+            $c->_extended_session_expires( my $updated = $c->calculate_initial_session_expires() );
+            $c->extend_session_id( $sid, $updated );
+
+            return $updated;
+
+        } else {
+
+            return $expires;
+
+        }
+
+    } else {
+
+        return;
+
+    }
+
 }
 
 sub change_session_expires {
@@ -1061,8 +1098,8 @@ hours).
 
 =item expiry_threshold
 
-The time (in seconds) before the session expiration to update the
-expiration time (and thus the session).
+Only update the session expiry time if it would otherwise expire
+within this many seconds from now.
 
 The purpose of this is to keep the session store from being updated
 when nothing else in the session is updated.
@@ -1203,6 +1240,8 @@ And countless other contributers from #catalyst. Thanks guys!
 
 Devin Austin (dhoss) <dhoss@cpan.org>
 
+Robert Rothenberg <rrwo@cpan.org> (on behalf of Foxtons Ltd.)
+
 =head1 COPYRIGHT & LICENSE
 
     Copyright (c) 2005 the aforementioned authors. All rights