From: skodak Date: Sun, 18 Jan 2009 23:06:52 +0000 (+0000) Subject: MDL-17942 lot more session refactoring X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=64d69e966c3fdf9ec86ccc55dd77fa7277d445cd;p=moodle.git MDL-17942 lot more session refactoring --- diff --git a/lib/sessionlib.php b/lib/sessionlib.php index 352af3186e..1b159d40de 100644 --- a/lib/sessionlib.php +++ b/lib/sessionlib.php @@ -58,7 +58,10 @@ abstract class session_stub implements moodle_session { global $CFG; if (!defined('NO_MOODLE_COOKIES')) { - if (CLI_SCRIPT) { + if (empty($CFG->version) or $CFG->version < 2009011600) { + // no session before sessions table gets greated + define('NO_MOODLE_COOKIES', true); + } else if (CLI_SCRIPT) { // CLI scripts can not have session define('NO_MOODLE_COOKIES', true); } else { @@ -89,10 +92,10 @@ abstract class session_stub implements moodle_session { session_name('MoodleSession'.$CFG->sessioncookie); session_set_cookie_params(0, $CFG->sessioncookiepath, $CFG->sessioncookiedomain, $CFG->cookiesecure, $CFG->cookiehttponly); - @session_start(); + session_start(); if (!isset($_SESSION['SESSION'])) { $_SESSION['SESSION'] = new object(); - if (!$newsession and !empty($CFG->rolesactive)) { + if (!$newsession) { $_SESSION['SESSION']->has_timed_out = true; } } @@ -116,6 +119,7 @@ abstract class session_stub implements moodle_session { return; } + // Initialize variable to pass-by-reference to headers_sent(&$file, &$line) $_SESSION = array(); $_SESSION['SESSION'] = new object(); $_SESSION['USER'] = new object(); @@ -123,22 +127,25 @@ abstract class session_stub implements moodle_session { if (isset($CFG->mnet_localhost_id)) { $_SESSION['USER']->mnethostid = $CFG->mnet_localhost_id; } - $SESSION = $_SESSION['SESSION']; // this may not work properly $USER = $_SESSION['USER']; // this may not work properly - // Initialize variable to pass-by-reference to headers_sent(&$file, &$line) $file = null; $line = null; if (headers_sent($file, $line)) { error_log('Can not terminate session properly - headers were already sent in file: '.$file.' on line '.$line); } - // now let's try to get a new session id - session_regenerate_id(); + $oldid = session_id(); - // close the session + // now let's try to get a new session id and delete the old one + session_regenerate_id(); + // write the new session session_write_close(); + + // make sure the old session gets killed, + // the optional param in session_regenerate_id() does not seem to work consistently + session_kill($oldid); } /** @@ -275,7 +282,6 @@ abstract class session_stub implements moodle_session { * Inits session storage. */ protected abstract function init_session_storage(); - } /** @@ -373,9 +379,7 @@ class database_session extends session_stub { $this->database->get_session_lock($record->id); } } catch (dml_exception $ex) { - if (!empty($CFG->rolesactive)) { - error_log('Can not read or insert database sessions'); - } + error_log('Can not read or insert database sessions'); return ''; } @@ -489,11 +493,20 @@ class database_session extends session_stub { } public function handler_gc($ignored_maxlifetime) { - $this->gc(); + session_gc(); return true; } } +/** + * returns true if legacy session used. + * @return bool true if legacy(==file) based session used + */ +function session_is_legacy() { + global $CFG, $DB; + return ((isset($CFG->dbsessions) and !$CFG->dbsessions) or !$DB->session_lock_supported()); +} + /** * Terminates all sessions, auth hooks are not executed. * Useful in ugrade scripts. @@ -501,15 +514,46 @@ class database_session extends session_stub { function session_kill_all() { global $CFG, $DB; + // always check db table - custom session classes use sessions table try { - // do not show any warnings - might be during upgrade/installation $DB->delete_records('sessions'); } catch (dml_exception $ignored) { + // do not show any warnings - might be during upgrade/installation } - $sessiondir = "$CFG->dataroot/sessions/"; - if (is_dir($sessiondir)) { - // TODO: delete all files, watch out some might be locked + if (session_is_legacy()) { + $sessiondir = "$CFG->dataroot/sessions"; + if (is_dir($sessiondir)) { + foreach (glob("$sessiondir/sess_*") as $filename) { + @unlink($filename); + } + } + } +} + +/** + * Mark session as accessed, prevents timeouts. + * @param string $sid + */ +function session_touch($sid) { + global $CFG, $DB; + + // always check db table - custom session classes use sessions table + try { + $sql = "UPDATE {sessions} SET timemodified=? WHERE sid=?"; + $params = array(time(), $sid); + $DB->execute($sql, $params); + } catch (dml_exception $ignored) { + // do not show any warnings - might be during upgrade/installation + } + + if (session_is_legacy()) { + $sid = clean_param($sid, PARAM_FILE); + $sessionfile = clean_param("$CFG->dataroot/sessions/sess_$sid", PARAM_FILE); + if (file_exists($sessionfile)) { + // if the file is locked it means that it will be updated anyway + @touch($sessionfile); + } } } @@ -521,15 +565,19 @@ function session_kill_all() { function session_kill($sid) { global $CFG, $DB; + // always check db table - custom session classes use sessions table try { - // do not show any warnings - might be during upgrade/installation - $$DB->delete_records('sessions', array('sid'=>$sid)); + $DB->delete_records('sessions', array('sid'=>$sid)); } catch (dml_exception $ignored) { + // do not show any warnings - might be during upgrade/installation } - $sessionfile = clean_param("$CFG->dataroot/sessions/$sid", PARAM_FILE); - if (file_exists($sessionfile)) { - // TODO: delete file, watch out might be locked + if (session_is_legacy()) { + $sid = clean_param($sid, PARAM_FILE); + $sessionfile = "$CFG->dataroot/sessions/sess_$sid"; + if (file_exists($sessionfile)) { + @unlink($sessionfile); + } } } @@ -542,10 +590,15 @@ function session_kill($sid) { function session_kill_user($userid) { global $CFG, $DB; + // always check db table - custom session classes use sessions table try { - // do not show any warnings - might be during upgrade/installation - $$DB->delete_records('sessions', array('userid'=>$userid)); + $DB->delete_records('sessions', array('userid'=>$userid)); } catch (dml_exception $ignored) { + // do not show any warnings - might be during upgrade/installation + } + + if (session_is_legacy()) { + // log error? } } @@ -562,10 +615,6 @@ function session_gc() { $maxlifetime = $CFG->sessiontimeout; - if (empty($CFG->rolesactive)) { - return; - } - try { /// kill all sessions of deleted users $DB->delete_records_select('sessions', "userid IN (SELECT id FROM {user} WHERE deleted <> 0)");