Don't start a session if it's known to be empty.

If an app only reads/checks the session there's no need to start a
session to know that the read/checked session value is empty.

Fixes #1981
This commit is contained in:
ADmad 2014-01-20 13:26:35 +05:30
parent 75dd2ff1fb
commit 84932fcc4a
4 changed files with 59 additions and 22 deletions

View file

@ -127,6 +127,13 @@ class CakeSession {
*/ */
protected static $_initialized = false; protected static $_initialized = false;
/**
* Session cookie name
*
* @var string
*/
protected static $_cookieName = null;
/** /**
* Pseudo constructor. * Pseudo constructor.
* *
@ -222,12 +229,10 @@ class CakeSession {
* @return boolean True if variable is there * @return boolean True if variable is there
*/ */
public static function check($name = null) { public static function check($name = null) {
if (!self::start()) { if (empty($name) || !self::_hasSession() || !self::start()) {
return false;
}
if (empty($name)) {
return false; return false;
} }
return Hash::get($_SESSION, $name) !== null; return Hash::get($_SESSION, $name) !== null;
} }
@ -321,7 +326,7 @@ class CakeSession {
* @return boolean Success * @return boolean Success
*/ */
public static function valid() { public static function valid() {
if (self::read('Config')) { if (self::start() && self::read('Config')) {
if (self::_validAgentAndTime() && self::$error === false) { if (self::_validAgentAndTime() && self::$error === false) {
self::$valid = true; self::$valid = true;
} else { } else {
@ -369,18 +374,19 @@ class CakeSession {
* Returns given session variable, or all of them, if no parameters given. * Returns given session variable, or all of them, if no parameters given.
* *
* @param string|array $name The name of the session variable (or a path as sent to Set.extract) * @param string|array $name The name of the session variable (or a path as sent to Set.extract)
* @return mixed The value of the session variable * @return mixed The value of the session variable, null if session not available,
* session not started, or provided name not found in the session.
*/ */
public static function read($name = null) { public static function read($name = null) {
if (!self::start()) { if (empty($name) && $name !== null) {
return false; return false;
} }
if (!self::_hasSession() || !self::start()) {
return null;
}
if ($name === null) { if ($name === null) {
return self::_returnSessionVars(); return self::_returnSessionVars();
} }
if (empty($name)) {
return false;
}
$result = Hash::get($_SESSION, $name); $result = Hash::get($_SESSION, $name);
if (isset($result)) { if (isset($result)) {
@ -410,12 +416,10 @@ class CakeSession {
* @return boolean True if the write was successful, false if the write failed * @return boolean True if the write was successful, false if the write failed
*/ */
public static function write($name, $value = null) { public static function write($name, $value = null) {
if (!self::start()) { if (empty($name) || !self::start()) {
return false;
}
if (empty($name)) {
return false; return false;
} }
$write = $name; $write = $name;
if (!is_array($name)) { if (!is_array($name)) {
$write = array($name => $value); $write = array($name => $value);
@ -443,6 +447,7 @@ class CakeSession {
$_SESSION = null; $_SESSION = null;
self::$id = null; self::$id = null;
self::$_cookieName = null;
} }
/** /**
@ -482,9 +487,12 @@ class CakeSession {
if (!isset($sessionConfig['ini']['session.cookie_lifetime'])) { if (!isset($sessionConfig['ini']['session.cookie_lifetime'])) {
$sessionConfig['ini']['session.cookie_lifetime'] = $sessionConfig['cookieTimeout'] * 60; $sessionConfig['ini']['session.cookie_lifetime'] = $sessionConfig['cookieTimeout'] * 60;
} }
if (!isset($sessionConfig['ini']['session.name'])) { if (!isset($sessionConfig['ini']['session.name'])) {
$sessionConfig['ini']['session.name'] = $sessionConfig['cookie']; $sessionConfig['ini']['session.name'] = $sessionConfig['cookie'];
} }
self::$_cookieName = $sessionConfig['ini']['session.name'];
if (!empty($sessionConfig['handler'])) { if (!empty($sessionConfig['handler'])) {
$sessionConfig['ini']['session.save_handler'] = 'user'; $sessionConfig['ini']['session.save_handler'] = 'user';
} }
@ -522,6 +530,39 @@ class CakeSession {
self::$sessionTime = self::$time + ($sessionConfig['timeout'] * 60); self::$sessionTime = self::$time + ($sessionConfig['timeout'] * 60);
} }
/**
* Get session cookie name.
*
* @return string
*/
protected static function _cookieName() {
if (self::$_cookieName !== null) {
return self::$_cookieName;
}
self::init();
$sessionConfig = Configure::read('Session');
if (isset($sessionConfig['ini']['session.name'])) {
return self::$_cookieName = $sessionConfig['ini']['session.name'];
}
$defaults = self::_defaultConfig($sessionConfig['defaults']);
if ($defaults) {
return self::$_cookieName = $defaults['cookie'];
}
return self::$_cookieName = ini_get('session.name');
}
/**
* Returns whether a session exists
* @return boolean
*/
protected static function _hasSession() {
return self::started() || isset($_COOKIE[self::_cookieName()]);
}
/** /**
* Find the handler class and make sure it implements the correct interface. * Find the handler class and make sure it implements the correct interface.
* *

View file

@ -135,10 +135,6 @@ class SessionComponentTest extends CakeTestCase {
* @return void * @return void
*/ */
public function testSessionIdConsistentAcrossRequestAction() { public function testSessionIdConsistentAcrossRequestAction() {
$Session = new SessionComponent($this->ComponentCollection);
$Session->check('Test');
$this->assertTrue(isset($_SESSION));
$Object = new Object(); $Object = new Object();
$Session = new SessionComponent($this->ComponentCollection); $Session = new SessionComponent($this->ComponentCollection);
$expected = $Session->id(); $expected = $Session->id();
@ -274,7 +270,7 @@ class SessionComponentTest extends CakeTestCase {
public function testSessionId() { public function testSessionId() {
unset($_SESSION); unset($_SESSION);
$Session = new SessionComponent($this->ComponentCollection); $Session = new SessionComponent($this->ComponentCollection);
$Session->check('test'); CakeSession::start();
$this->assertEquals(session_id(), $Session->id()); $this->assertEquals(session_id(), $Session->id());
} }

View file

@ -17,6 +17,7 @@
*/ */
App::uses('I18n', 'I18n'); App::uses('I18n', 'I18n');
App::uses('CakeSession', 'Model/Datasource');
/** /**
* I18nTest class * I18nTest class
@ -1517,7 +1518,7 @@ class I18nTest extends CakeTestCase {
* @return void * @return void
*/ */
public function testSetLanguageWithSession() { public function testSetLanguageWithSession() {
$_SESSION['Config']['language'] = 'po'; CakeSession::write('Config.language', 'po');
$singular = $this->_singular(); $singular = $this->_singular();
$this->assertEquals('Po (translated)', $singular); $this->assertEquals('Po (translated)', $singular);
@ -1548,7 +1549,7 @@ class I18nTest extends CakeTestCase {
$this->assertTrue(in_array('23 everything else (po translated)', $plurals)); $this->assertTrue(in_array('23 everything else (po translated)', $plurals));
$this->assertTrue(in_array('24 everything else (po translated)', $plurals)); $this->assertTrue(in_array('24 everything else (po translated)', $plurals));
$this->assertTrue(in_array('25 everything else (po translated)', $plurals)); $this->assertTrue(in_array('25 everything else (po translated)', $plurals));
unset($_SESSION['Config']['language']); CakeSession::delete('Config.language');
} }
/** /**

View file

@ -114,7 +114,6 @@ class CakeSessionTest extends CakeTestCase {
'cookieTimeout' => 120, 'cookieTimeout' => 120,
'ini' => array(), 'ini' => array(),
)); ));
TestCakeSession::init();
} }
/** /**