--- /dev/null
+<?php\r
+\r
+/**\r
+ * @file src/Core/Session.php\r
+ */\r
+namespace Friendica\Core;\r
+\r
+use Friendica\Core\Session\DatabaseSessionHandler;\r
+use Friendica\Core\Session\MemcacheSessionHandler;\r
+\r
+/**\r
+ * High-level Session service class\r
+ *\r
+ * @author Hypolite Petovan <mrpetovan@gmail.com>\r
+ */\r
+class Session\r
+{\r
+ public static $exists = false;\r
+ public static $expire = 180000;\r
+\r
+ public static function init()\r
+ {\r
+ ini_set('session.gc_probability', 50);\r
+ ini_set('session.use_only_cookies', 1);\r
+ ini_set('session.cookie_httponly', 1);\r
+\r
+ if (Config::get('system', 'ssl_policy') == SSL_POLICY_FULL) {\r
+ ini_set('session.cookie_secure', 1);\r
+ }\r
+\r
+ if (!Config::get('system', 'disable_database_session')) {\r
+ $memcache = Cache::memcache();\r
+ if (is_object($memcache)) {\r
+ $SessionHandler = new MemcacheSessionHandler($memcache);\r
+ } else {\r
+ $SessionHandler = new DatabaseSessionHandler();\r
+ }\r
+\r
+ session_set_save_handler($SessionHandler);\r
+ }\r
+ }\r
+\r
+ public static function exists($name)\r
+ {\r
+ return isset($_SESSION[$name]);\r
+ }\r
+\r
+ public static function get($name)\r
+ {\r
+ return defaults($_SESSION, $name, null);\r
+ }\r
+\r
+ public static function set($name, $value)\r
+ {\r
+ $_SESSION[$name] = $value;\r
+ }\r
+}\r
--- /dev/null
+<?php\r
+\r
+namespace Friendica\Core\Session;\r
+\r
+use Friendica\BaseObject;\r
+use Friendica\Core\Session;\r
+use Friendica\Database\DBM;\r
+use SessionHandlerInterface;\r
+use dba;\r
+\r
+require_once 'boot.php';\r
+require_once 'include/dba.php';\r
+require_once 'include/text.php';\r
+\r
+/**\r
+ * SessionHandler using database\r
+ *\r
+ * @author Hypolite Petovan <mrpetovan@gmail.com>\r
+ */\r
+class DatabaseSessionHandler extends BaseObject implements SessionHandlerInterface\r
+{\r
+ public function open($save_path, $session_name)\r
+ {\r
+ return true;\r
+ }\r
+\r
+ public function read($session_id)\r
+ {\r
+ if (!x($session_id)) {\r
+ return '';\r
+ }\r
+\r
+ $session = dba::selectFirst('session', ['data'], ['sid' => $session_id]);\r
+ if (DBM::is_result($session)) {\r
+ Session::$exists = true;\r
+ return $session['data'];\r
+ }\r
+ logger("no data for session $session_id", LOGGER_TRACE);\r
+\r
+ return '';\r
+ }\r
+\r
+ /**\r
+ * @brief Standard PHP session write callback\r
+ *\r
+ * This callback updates the DB-stored session data and/or the expiration depending\r
+ * on the case. Uses the Session::expire global for existing session, 5 minutes\r
+ * for newly created session.\r
+ *\r
+ * @param string $session_id Session ID with format: [a-z0-9]{26}\r
+ * @param string $session_data Serialized session data\r
+ * @return boolean Returns false if parameters are missing, true otherwise\r
+ */\r
+ public function write($session_id, $session_data)\r
+ {\r
+ if (!$session_id) {\r
+ return false;\r
+ }\r
+\r
+ if (!$session_data) {\r
+ return true;\r
+ }\r
+\r
+ $expire = time() + Session::$expire;\r
+ $default_expire = time() + 300;\r
+\r
+ if (Session::$exists) {\r
+ $fields = ['data' => $session_data, 'expire' => $expire];\r
+ $condition = ["`sid` = ? AND (`data` != ? OR `expire` != ?)", $session_id, $session_data, $expire];\r
+ dba::update('session', $fields, $condition);\r
+ } else {\r
+ $fields = ['sid' => $session_id, 'expire' => $default_expire, 'data' => $session_data];\r
+ dba::insert('session', $fields);\r
+ }\r
+\r
+ return true;\r
+ }\r
+\r
+ public function close()\r
+ {\r
+ return true;\r
+ }\r
+\r
+ public function destroy($id)\r
+ {\r
+ dba::delete('session', ['sid' => $id]);\r
+ return true;\r
+ }\r
+\r
+ public function gc($maxlifetime)\r
+ {\r
+ dba::delete('session', ["`expire` < ?", time()]);\r
+ return true;\r
+ }\r
+}\r
--- /dev/null
+<?php\r
+\r
+namespace Friendica\Core\Session;\r
+\r
+use Friendica\BaseObject;\r
+use Friendica\Core\Session;\r
+use SessionHandlerInterface;\r
+use Memcache;\r
+\r
+require_once 'boot.php';\r
+require_once 'include/text.php';\r
+\r
+/**\r
+ * SessionHandler using Memcache\r
+ *\r
+ * @author Hypolite Petovan <mrpetovan@gmail.com>\r
+ */\r
+class MemcacheSessionHandler extends BaseObject implements SessionHandlerInterface\r
+{\r
+ /**\r
+ * @var Memcache\r
+ */\r
+ private $memcache = null;\r
+\r
+ /**\r
+ *\r
+ * @param Memcache $memcache\r
+ */\r
+ public function __construct(Memcache $memcache)\r
+ {\r
+ $this->memcache = $memcache;\r
+ }\r
+\r
+ public function open($save_path, $session_name)\r
+ {\r
+ return true;\r
+ }\r
+\r
+ public function read($session_id)\r
+ {\r
+ if (!x($session_id)) {\r
+ return '';\r
+ }\r
+\r
+ $data = $this->memcache->get(self::getApp()->get_hostname() . ":session:" . $session_id);\r
+ if (!is_bool($data)) {\r
+ Session::$exists = true;\r
+ return $data;\r
+ }\r
+ logger("no data for session $session_id", LOGGER_TRACE);\r
+ return '';\r
+ }\r
+\r
+ /**\r
+ * @brief Standard PHP session write callback\r
+ *\r
+ * This callback updates the stored session data and/or the expiration depending\r
+ * on the case. Uses the Session::expire for existing session, 5 minutes\r
+ * for newly created session.\r
+ *\r
+ * @param string $session_id Session ID with format: [a-z0-9]{26}\r
+ * @param string $session_data Serialized session data\r
+ * @return boolean Returns false if parameters are missing, true otherwise\r
+ */\r
+ public function write($session_id, $session_data)\r
+ {\r
+ if (!$session_id) {\r
+ return false;\r
+ }\r
+\r
+ if (!$session_data) {\r
+ return true;\r
+ }\r
+\r
+ $expire = time() + Session::$expire;\r
+\r
+ $this->memcache->set(\r
+ self::getApp()->get_hostname() . ":session:" . $session_id,\r
+ $session_data,\r
+ MEMCACHE_COMPRESSED,\r
+ $expire\r
+ );\r
+\r
+ return true;\r
+ }\r
+\r
+ public function close()\r
+ {\r
+ return true;\r
+ }\r
+\r
+ public function destroy($id)\r
+ {\r
+ $this->memcache->delete(self::getApp()->get_hostname() . ":session:" . $id);\r
+ return true;\r
+ }\r
+\r
+ public function gc($maxlifetime)\r
+ {\r
+ return true;\r
+ }\r
+}\r