From: Michael M Slusarz Date: Thu, 14 Oct 2010 04:31:06 +0000 (-0600) Subject: Add code needed to manually mark session data as dirty X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=53eeaef28ac9dd7aeeac25f780139c2d471bdce7;p=horde.git Add code needed to manually mark session data as dirty Disable by default in Horde for now (will be enabled when all session access code has been converted to Horde_Session). --- diff --git a/framework/Core/lib/Horde/Core/Factory/SessionHandler.php b/framework/Core/lib/Horde/Core/Factory/SessionHandler.php index b24a4ad88..c65d48b1a 100644 --- a/framework/Core/lib/Horde/Core/Factory/SessionHandler.php +++ b/framework/Core/lib/Horde/Core/Factory/SessionHandler.php @@ -69,10 +69,9 @@ class Horde_Core_Factory_SessionHandler } $params['logger'] = $logger; - $params['modified'] = array( - 'get' => array($this, 'getModified'), - 'set' => array($this, 'setModified') - ); + // TODO: Uncomment once all session data is saved through + // Horde_Session. + //$params['no_md5'] = true $params['parse'] = array($this, 'readSessionData'); $driver = basename(strtolower($driver)); @@ -125,18 +124,4 @@ class Horde_Core_Factory_SessionHandler return false; } - /** - */ - public function getModified() - { - return $GLOBALS['session']['horde:session_mod']; - } - - /** - */ - public function setModified($date) - { - $GLOBALS['session']['horde:session_mod'] = $date; - } - } diff --git a/framework/Core/lib/Horde/Session.php b/framework/Core/lib/Horde/Session.php index c3e3468ef..0983bc2dd 100644 --- a/framework/Core/lib/Horde/Session.php +++ b/framework/Core/lib/Horde/Session.php @@ -105,6 +105,20 @@ class Horde_Session implements ArrayAccess /* Is this key serialized? */ $_SESSION[self::SERIALIZED] = array(); } + + /* Determine if we need to force write the session to avoid a + * session timeout, even though the session is unchanged. + * Theory: On initial login, set the current time plus half of the + * max lifetime in the session. Then check this timestamp before + * saving. If we exceed, force a write of the session and set a + * new timestamp. Why half the maxlifetime? It guarantees that if + * we are accessing the server via a periodic mechanism (think + * folder refreshing in IMP) that we will catch this refresh. */ + $curr_time = time(); + if ($curr_time >= intval($this['horde:session_mod'])) { + $this['horde:session_mod'] = $curr_time + (ini_get('session.gc_maxlifetime') / 2); + $this->sessionHandler->changed = true; + } } } @@ -334,6 +348,7 @@ class Horde_Session implements ArrayAccess } $_SESSION[$ob->app][$ob->name] = $value; + $this->sessionHandler->changed = true; } /** diff --git a/framework/SessionHandler/lib/Horde/SessionHandler.php b/framework/SessionHandler/lib/Horde/SessionHandler.php index 6df6f5882..a943715ef 100644 --- a/framework/SessionHandler/lib/Horde/SessionHandler.php +++ b/framework/SessionHandler/lib/Horde/SessionHandler.php @@ -1,7 +1,6 @@ * @category Horde + * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @package SessionHandler */ abstract class Horde_SessionHandler { /** - * Hash containing connection parameters. + * If true, indicates the session data has changed. * - * @var array + * @var boolean */ - protected $_params = array(); + public $changed = false; /** - * Initial session data signature. + * Has a connection been made to the backend? * - * @var string + * @var boolean */ - protected $_sig; + protected $_connected = false; /** - * Force saving the session data? + * A logger instance. * - * @var boolean + * @var Horde_Log_Logger */ - protected $_force = false; + protected $_logger; /** - * Has a connection been made to the backend? + * Hash containing connection parameters. * - * @var boolean + * @var array */ - protected $_connected = false; + protected $_params = array(); /** - * A logger instance. + * Initial session data signature. * - * @var Horde_Log_Logger + * @var string */ - protected $_logger; + protected $_sig; /** * Constructor. * * @param array $params Parameters: *
-     * 'logger' - (Horde_Log_Logger) A logger instance.
-     *            DEFAULT: No logging
-     * 'modified' - (array) Callbacks used to store the session last modified
-     *              value.  Needs to define two keys: 'get' and 'set'. 'get'
-     *              returns the last modified value, 'set' receives the last
-     *              modified value as the only parameter.
-     *              DEFAULT: Not saved
-     * 'noset' - (boolean) If true, don't set the save handler.
-     *           DEFAULT: false
-     * 'parse' - (callback) A callback function that parses session
-     *           information into an array. Is passed the raw session data
-     *           as the only argument; expects either false or an array of
-     *           session data as a return.
-     *           DEFAULT: No
+     * logger - (Horde_Log_Logger) A logger instance.
+     *          DEFAULT: No logging
+     * no_md5 - (boolean) If true, does not do MD5 signatures of the session
+     *          to determine if the session has changed. If true, calling code
+     *          is responsible for marking $changed as true when the session
+     *          data has changed.
+     *          DEFAULT: false
+     * noset - (boolean) If true, don't set the save handler.
+     *         DEFAULT: false
+     * parse - (callback) A callback function that parses session
+     *         information into an array. Is passed the raw session data
+     *         as the only argument; expects either false or an array of
+     *         session data as a return.
+     *         DEFAULT: No
      * 
*/ public function __construct(array $params = array()) @@ -81,10 +81,6 @@ abstract class Horde_SessionHandler $this->_params = $params; - if (isset($this->_params['modified'])) { - register_shutdown_function(array($this, 'shutdown')); - } - if (empty($this->_params['noset'])) { ini_set('session.save_handler', 'user'); session_set_save_handler( @@ -110,27 +106,6 @@ abstract class Horde_SessionHandler } /** - * Shutdown function. - * - * Used to determine if we need to write the session to avoid a session - * timeout, even though the session is unchanged. - * Theory: On initial login, set the current time plus half of the max - * lifetime in the session. Then check this timestamp before saving. - * If we exceed, force a write of the session and set a new timestamp. - * Why half the maxlifetime? It guarantees that if we are accessing the - * server via a periodic mechanism (think folder refreshing in IMP) that - * we will catch this refresh. - */ - public function shutdown() - { - $curr_time = time(); - if ($curr_time >= intval(call_user_func($this->_params['modified']['get']))) { - call_user_func($this->_params['modified']['set'], $curr_time + (ini_get('session.gc_maxlifetime') / 2)); - $this->_force = true; - } - } - - /** * Open the backend. * * @param string $save_path The path to the session object. @@ -205,7 +180,9 @@ abstract class Horde_SessionHandler public function read($id) { $result = $this->_read($id); - $this->_sig = md5($result); + if (empty($this->_params['no_md5'])) { + $this->_sig = md5($result); + } return $result; } @@ -230,14 +207,17 @@ abstract class Horde_SessionHandler */ public function write($id, $session_data) { - if (!$this->_force && ($this->_sig == md5($session_data))) { - if ($this->_logger) { - $this->_logger->log('Session data unchanged (id = ' . $id . ')', 'DEBUG'); - } - return true; + if ($this->changed || + (empty($this->_params['no_md5']) && + ($this->_sig != md5($session_data)))) { + return $this->_write($id, $session_data); } - return $this->_write($id, $session_data); + if ($this->_logger) { + $this->_logger->log('Session data unchanged (id = ' . $id . ')', 'DEBUG'); + } + + return true; } /**