summaryrefslogtreecommitdiffstats
path: root/system/libraries/Session/drivers/Session_files_driver.php
diff options
context:
space:
mode:
authorAndrey Andreev <narf@devilix.net>2014-05-31 15:08:30 +0200
committerAndrey Andreev <narf@devilix.net>2014-05-31 15:08:30 +0200
commit47a47fb9fafdb26206d01d846d8013f6e883eb37 (patch)
treef4965d3685f9937c6b1b529c3c51777062d7fe01 /system/libraries/Session/drivers/Session_files_driver.php
parentf8b6180f37841362d28e78eb25aaf38c55da0839 (diff)
Initial version of new Session library
Diffstat (limited to 'system/libraries/Session/drivers/Session_files_driver.php')
-rw-r--r--system/libraries/Session/drivers/Session_files_driver.php276
1 files changed, 276 insertions, 0 deletions
diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php
new file mode 100644
index 000000000..4acbcf6c5
--- /dev/null
+++ b/system/libraries/Session/drivers/Session_files_driver.php
@@ -0,0 +1,276 @@
+<?php
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.2.4 or newer
+ *
+ * NOTICE OF LICENSE
+ *
+ * Licensed under the Open Software License version 3.0
+ *
+ * This source file is subject to the Open Software License (OSL 3.0) that is
+ * bundled with this package in the files license.txt / license.rst. It is
+ * also available through the world wide web at this URL:
+ * http://opensource.org/licenses/OSL-3.0
+ * If you did not receive a copy of the license and are unable to obtain it
+ * through the world wide web, please send an email to
+ * licensing@ellislab.com so we can send you a copy immediately.
+ *
+ * @package CodeIgniter
+ * @author Andrey Andreev
+ * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
+ * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
+ * @link http://codeigniter.com
+ * @since Version 3.0
+ * @filesource
+ */
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/**
+ * CodeIgniter Session Files Driver
+ *
+ * @package CodeIgniter
+ * @subpackage Libraries
+ * @category Sessions
+ * @author Andrey Andreev
+ * @link http://codeigniter.com/user_guide/libraries/sessions.html
+ */
+class CI_Session_files_driver extends CI_Session_driver implements SessionHandlerInterface {
+
+ /**
+ * Save path
+ *
+ * @var string
+ */
+ protected $_save_path;
+
+ /**
+ * File handle
+ *
+ * @var resource
+ */
+ protected $_file_handle;
+
+ /**
+ * File name
+ *
+ * @var resource
+ */
+ protected $_file_path;
+
+ /**
+ * File new flag
+ *
+ * @var bool
+ */
+ protected $_file_new;
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Class constructor
+ *
+ * @param array $params Configuration parameters
+ * @return void
+ */
+ public function __construct(&$params)
+ {
+ parent::__construct($params);
+
+ if (isset($this->_save_path))
+ {
+ $this->_save_path = rtrim($this->_save_path, '/\\');
+ ini_set('session.save_path', $this->_save_path);
+ }
+ else
+ {
+ $this->_save_path = rtrim(ini_get('session.save_path'), '/\\');
+ }
+ }
+
+ // ------------------------------------------------------------------------
+
+ public function open($save_path, $name)
+ {
+ if ( ! is_dir($save_path) && ! mkdir($save_path, 0700, TRUE))
+ {
+ log_message('error', "Session: Configured save path '".$this->_save_path."' is not a directory, doesn't exist or cannot be created.");
+ return FALSE;
+ }
+
+ $this->_save_path = $save_path;
+ $this->_file_path = $this->_save_path.DIRECTORY_SEPARATOR
+ .$name // we'll use the session cookie name as a prefix to avoid collisions
+ .($this->_match_ip ? md5($_SERVER['REMOTE_ADDR']) : '');
+
+ return TRUE;
+ }
+
+ // ------------------------------------------------------------------------
+
+ public function read($session_id)
+ {
+ // This might seem weird, but PHP 5.6 introduces session_reset(),
+ // which re-reads session data
+ if ($this->_file_handle === NULL)
+ {
+ $this->_file_path .= $session_id;
+
+ // Just using fopen() with 'c+b' mode would be perfect, but it is only
+ // available since PHP 5.2.6 and we have to set permissions for new files,
+ // so we'd have to hack around this ...
+ if (($this->_file_new = ! file_exists($this->_file_path)) === TRUE)
+ {
+ if (($this->_file_handle = fopen($this->_file_path, 'w+b')) === FALSE)
+ {
+ log_message('error', "Session: File '".$this->_file_path."' doesn't exist and cannot be created.");
+ return FALSE;
+ }
+ }
+ elseif (($this->_file_handle = fopen($this->_file_path, 'r+b')) === FALSE)
+ {
+ log_message('error', "Session: Unable to open file '".$this->_file_path."'.");
+ return FALSE;
+ }
+
+ if (flock($this->_file_handle, LOCK_EX) === FALSE)
+ {
+ log_message('error', "Session: Unable to obtain lock for file '".$this->_file_path."'.");
+ fclose($this->_file_handle);
+ $this->_file_handle = NULL;
+ return FALSE;
+ }
+
+ if ($this->_file_new)
+ {
+ chmod($this->_file_path, 0600);
+ $this->_fingerprint = md5('');
+ return '';
+ }
+ }
+ else
+ {
+ rewind($this->_file_handle);
+ }
+
+ $session_data = '';
+ for ($read = 0, $length = filesize($this->_file_path); $read < $length; $read += strlen($buffer))
+ {
+ if (($buffer = fread($this->_file_handle, $length - $read)) === FALSE)
+ {
+ break;
+ }
+
+ $session_data .= $buffer;
+ }
+
+ $this->_fingerprint = md5($session_data);
+ return $session_data;
+ }
+
+ public function write($session_id, $session_data)
+ {
+ if ( ! is_resource($this->_file_handle))
+ {
+ return FALSE;
+ }
+ elseif ($this->_fingerprint === md5($session_data))
+ {
+ return ($this->_file_new)
+ ? TRUE
+ : touch($this->_file_path);
+ }
+
+ if ( ! $this->_file_new)
+ {
+ ftruncate($this->_file_handle, 0);
+ rewind($this->_file_handle);
+ }
+
+ for ($written = 0, $length = strlen($session_data); $written < $length; $written += $result)
+ {
+ if (($result = fwrite($this->_file_handle, substr($session_data, $written))) === FALSE)
+ {
+ break;
+ }
+ }
+
+ if ( ! is_int($result))
+ {
+ $this->_fingerprint = md5(substr($session_data, 0, $written));
+ log_message('error', 'Session: Unable to write data.');
+ return FALSE;
+ }
+
+ $this->_fingerprint = md5($session_data);
+ return TRUE;
+ }
+
+ // ------------------------------------------------------------------------
+
+ public function close()
+ {
+ if (is_resource($this->_file_handle))
+ {
+ flock($this->_file_handle, LOCK_UN);
+ fclose($this->_file_handle);
+
+ $this->_file_handle = $this->_file_new = NULL;
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+ // ------------------------------------------------------------------------
+
+ public function destroy($session_id)
+ {
+ if ($this->close())
+ {
+ return unlink($this->_file_path) && $this->_cookie_destroy();
+ }
+ elseif ($this->_file_path !== NULL)
+ {
+ clearstatcache();
+ return file_exists($this->_file_path)
+ ? (unlink($this->_file_path) && $this->_cookie_destroy())
+ : TRUE;
+ }
+
+ return FALSE;
+ }
+
+ // ------------------------------------------------------------------------
+
+ public function gc($maxlifetime)
+ {
+ if ( ! is_dir($this->_save_path) OR ($files = scandir($this->_save_path)) === FALSE)
+ {
+ log_message('debug', "Session: Garbage collector couldn't list files under directory '".$this->_save_path."'.");
+ return FALSE;
+ }
+
+ $ts = time() - $maxlifetime;
+
+ foreach ($files as $file)
+ {
+ // If the filename doesn't match this pattern, it's either not a session file or is not ours
+ if ( ! preg_match('/(?:[0-9a-f]{32})?[0-9a-f]{40}$/i', $file)
+ OR ! is_file($this->_save_path.DIRECTORY_SEPARATOR.$file)
+ OR ($mtime = filemtime($file)) === FALSE
+ OR $mtime > $ts)
+ {
+ continue;
+ }
+
+ unlink($this->_save_path.DIRECTORY_SEPARATOR.$file);
+ }
+
+ return TRUE;
+ }
+
+}
+
+/* End of file Session_files_driver.php */
+/* Location: ./system/libraries/Session/drivers/Session_files_driver.php */ \ No newline at end of file