ÿØÿà JFIF    ÿÛ „  ( %!1"%)+...383-7(-.+  -%%--------+------------/----------------------------ÿÀ  ¶" ÿÄ     ÿÄ @    !1AQaq‘¡"±ÁÑð2’BRráS‚ñ3b¢CT²Ò #cÿÄ    ÿÄ '   1!AQ2a"‘±#ÿÚ   ? ò(/p‘—–¢·,M|¯G»R£üešT. ôŸEoCFñ‡ 4ÔkåóxR|µÁ¨ÓDà!Ç´µ˜‡p ÍQ‹§!þž^õWsŒy  åÁ§$á«%ºq˜™JyyË0y«^Ϗ -3ÃÏËÈ£Æ\P’ä„s&•‹Üs üô'àWt¹pñCp$bÚF`·7.^)¾!)ÒÙ˜–ÅÏš^h¾ø³·ìe±ŒaeÖ—Í,e=B}Jéߦ$$½—šÙÜCC¯¶è8β–Åkèwx LÉngT±æ¹£Ócœ¿Í/©Éÿ ‰ÚCÒ­mq;Tt¶–}0"zÖPcd1š­¤tˆ„ÐÓâqú[™öUCŠ2޿د­É(¸ßúçšmW,Ò ºf‹Ån™ÄLêÁ8üÁkÁ€L¥ÍuJ1œôrÂSŒÓöt!7EUíïb)AËi¬â-ÙHk8òÁiXYwÅ)O^"ÇØriÛô{»wRUKÙÏÚlÓ¬€‚’שT ] ªb—ÊîKC^×M“xùäñz¬zJ× {4[¹M'IÆeH1LCWÕ]œûº WDæà°OÅ‚¹c²ÞuA–rL`HšpCez‡V’— Ž‚Ë„–ñ­'µR0ÕÖ=À:±G»C\nÆÉ5*¢ †3šhQ4ýÒi$Õ1"Ü]¢p-q3zcQ$ªö¨¥æf›‘»´ÝÚHá„e²JÇ–iÊ:·à¬Øc5Åk»Laª*wi [0Ówk ¦a¦0Õ²ÅÅ‚T¸’³q:Æ<¹ú Ò˜Æ}2VE•Ѐp¡Ô3Úº …h³^LJºçì¥Ánó|˜ÖˆÎˆ+« ¦dø‘Mº–d\ªDðÛ„Ì×LÝ——Ð9Ç|•FèçVm™¨€™3õS–9Äå¢<̉Ìm¢±`·º˜&Z²ž Ë®D«¶»6™‰©­HÈ Àá«h­i³04æ’hxœi3ï¨(ÓL·†‹¶ËpŒ ƒÜÒ? :õdsÀ –3æÓ·Üjâ¬9—]8n¼&]I F£¼…ì–—Œ0v°LǐÅfÛ2TÖ’aµ˜N@ÖBSÏ^à´4-±°b×nÈÈœÆD=KdŒø…ÄÈK,›ÖR§fjü$^ÔÎ!„6^ s:Üun\ôkCÞò÷<—Lúl Í›G¹ÀPá¼Nc¡šÒ…ÙWͳœ±vÊáЄ×9‹P‰cEØ‘™›µŸP<×g1 º©Ø¬wiÁ^l5× I/';Ë+´Z‡ÓÄFÕp[Èð’ HÄ ó 9¬Dl4“é±Ï”V=^Hð;žLädÉa‚°Ë,#/Ž~²BÔÛ QãñQtIeórVB,ÏÂf‹4#Μc‹É3ZIÖ Œ¢¥·üxa‡Ãçè„jŠ[5 Ä!U?,3žÎ×…ðdÓ÷háŠA‰ìÄ4÷ÃÜZÃE{‰®+W\ZÍE[‰»µk»MÝ­`¢©†˜ÃV‹-f¢¡†¢a«eŠ%«Y¨©q%jâd,Ôq`) ¤¦…šˆ ¦E>0Ùb²t–Ÿ  ÷jsςҒKÈcø(é›;k(’#ôŒQ ™C> õ³M9óºÆµ¤çâ;uÀ)5>RÔ¸fÓ~Ȧ—’-$fe«"FâUˆÊwµPÏu w+"åÉó¨6s™Û9(À¨ù©hE°½†n`m~“@©›p!Vkhµ Á1šbEqqÊ@ºèl›2 –Yã%‘‚hÛ{a¶‡ÅÞM²¬çL34®Çl]®‹ŽØŒm'RÜe35æöˆ­Á­ cP9šeÁköo´L³Ì=p8]”‡B¶,šº|ɏdzXˆØk*ÇÚ{#ñ‰pã(€¶‡9ý'šÜ³½¯kƒ†Â’ëSOƒ•Å®H6+a¢µˆ‹Y¨b˜b+XˆÖ!°u!¢"µˆˆn2ˆ Å0Ä`Å Ô®c(ÓÜGº•Ä»Œ âWî%q.áÐÄ÷î%umÍ£+ÜQ,Vn¦-GphU¸¢X­&,Gt ·K¢ÅÅ·¥RÄÊÉbKn N­R2g$VµÕó Qr#–ÓZUÏð0ÎtÙÀœz ëöo“Îk¯n„T°"SÞ+³/…€½"ižãO%Í%&Δâ‘ËØ´IˆÓ°Ë‰ÞM3.™yçÁzit›`4C`k¢¼á!álÄï sÂ[×!¤l¾æo"ƒIÔ'@ªu)3›ô®“@Z à¾] üœ'‡4¸PÞkÁ-qÄH‰ÓÍBd´ÿ —¹°ÄA&ÊUC„öz‚‚RæŠtf¬>˜ÑidšEçÑL÷áý¡V±h§­c¿¥¨ƒ@g¼…Ýö^ÞËc.ž„æ“I[ ª+·zÐÒÚ,½Ð»¶€C›7jk$๖€Ž¾ÅÙpp¶ÍþéΤ ½ØÎŒq ñpæžÅ¥#Øâ49ÃÂK^MYV“,¶Éz_òæ:…;Õ«¦I3âJ£¤û5$7Èxün\â]Êe¯(Ÿ&Ž‹¶2<6Ćf× æ¢ƱqWı[(ÙÂŽç‚T7¨@ÈÉÍß‚ïÙ"&3TYlGށ†)†#5ŠA©^T2ÆÁ†)©†©†¤yGXÁ†©"†)©¼ÅV WS†#©]R–r‹q5ÕbâWþBh¯u+ªÅÄ×ü„nÑ^êkªÁj‰jeœWˆÕÕ`µDµ2Ì+Ä µDµµ5Ô{¤Þ0RF’H÷AÛ<ÊÁ§ ƈæ0Ñ£ê4 öÚµ[¬/1²€â<-¬šö²r×0o×w ´xÐÒË„ g01¬„åEM蛇Ã\6µE›‘fÙO k÷CºnÓ1`iîÒ² áÂ!ÑLÄÿ ³¬\õ*:M=Ç»c‹2[‰ØsÕLò\ŒK L^™üÄN\¶#» Ç\……ßïIœÉ$¸ÎñÍ®ÔHÇ Ûí/´>Li”„†g^$ 7NÍÑÑ2M2ªNg=k½Ð}Ÿl6‡ —JWˆ”ÞéT·+µ¦üÂFè¢Vs6ýÆ4»2+2IÝ9ô9®ÇGÙÇ1+Ä8;*Õ§ž½D*îÑWÚçá3Ma¤·ˆ¥t}š²Ü…Q+Æüµ8HíS”üxGéÁˆ¦Ël„éÈ 5 µÄƒ6äÜ(kIš¯S†fÖ&¸®×v|Äyˆ*禌Éù@7-®Ä[]ÎÖ¿ê`º…=:…žJVnݳvðÖKE¼‚ »mà ÷f®:Ë ™–4rð¡4` ܹçž~‹C=œ…¾Ïj|VDtK.ƒ"9 Ï ­–éXá³6WÒïIL-Ї Ç PKw\XC--Session_files_driver.phpnu[_config['save_path'])) { $this->_config['save_path'] = rtrim($this->_config['save_path'], '/\\'); ini_set('session.save_path', $this->_config['save_path']); } else { log_message('debug', 'Session: "sess_save_path" is empty; using "session.save_path" value from php.ini.'); $this->_config['save_path'] = rtrim(ini_get('session.save_path'), '/\\'); } $this->_sid_regexp = $this->_config['_sid_regexp']; isset(self::$func_overload) OR self::$func_overload = ( ! is_php('8.0') && extension_loaded('mbstring') && @ini_get('mbstring.func_overload')); } // ------------------------------------------------------------------------ /** * Open * * Sanitizes the save_path directory. * * @param string $save_path Path to session files' directory * @param string $name Session cookie name * @return bool */ public function open($save_path, $name) { if ( ! is_dir($save_path)) { if ( ! mkdir($save_path, 0700, TRUE)) { log_message('error', "Session: Configured save path '".$this->_config['save_path']."' is not a directory, doesn't exist or cannot be created."); return $this->_failure; } } elseif ( ! is_writable($save_path)) { log_message('error', "Session: Configured save path '".$this->_config['save_path']."' is not writable by the PHP process."); return $this->_failure; } $this->_config['save_path'] = $save_path; $this->_file_path = $this->_config['save_path'].DIRECTORY_SEPARATOR .$name // we'll use the session cookie name as a prefix to avoid collisions .($this->_config['match_ip'] ? md5($_SERVER['REMOTE_ADDR']) : ''); $this->php5_validate_id(); return $this->_success; } // ------------------------------------------------------------------------ /** * Read * * Reads session data and acquires a lock * * @param string $session_id Session ID * @return string Serialized session data */ 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_new = ! file_exists($this->_file_path.$session_id); if (($this->_file_handle = fopen($this->_file_path.$session_id, 'c+b')) === FALSE) { log_message('error', "Session: Unable to open file '".$this->_file_path.$session_id."'."); return $this->_failure; } if (flock($this->_file_handle, LOCK_EX) === FALSE) { log_message('error', "Session: Unable to obtain lock for file '".$this->_file_path.$session_id."'."); fclose($this->_file_handle); $this->_file_handle = NULL; return $this->_failure; } // Needed by write() to detect session_regenerate_id() calls $this->_session_id = $session_id; if ($this->_file_new) { chmod($this->_file_path.$session_id, 0600); $this->_fingerprint = md5(''); return ''; } // Prevent possible data corruption // See https://github.com/bcit-ci/CodeIgniter/issues/5857 clearstatcache(TRUE, $this->_file_path.$session_id); } // We shouldn't need this, but apparently we do ... // See https://github.com/bcit-ci/CodeIgniter/issues/4039 elseif ($this->_file_handle === FALSE) { return $this->_failure; } else { rewind($this->_file_handle); } $session_data = ''; for ($read = 0, $length = filesize($this->_file_path.$session_id); $read < $length; $read += self::strlen($buffer)) { if (($buffer = fread($this->_file_handle, $length - $read)) === FALSE) { break; } $session_data .= $buffer; } $this->_fingerprint = md5($session_data); return $session_data; } // ------------------------------------------------------------------------ /** * Write * * Writes (create / update) session data * * @param string $session_id Session ID * @param string $session_data Serialized session data * @return bool */ public function write($session_id, $session_data) { // If the two IDs don't match, we have a session_regenerate_id() call // and we need to close the old handle and open a new one if ($session_id !== $this->_session_id && ($this->close() === $this->_failure OR $this->read($session_id) === $this->_failure)) { return $this->_failure; } if ( ! is_resource($this->_file_handle)) { return $this->_failure; } elseif ($this->_fingerprint === md5($session_data)) { return ( ! $this->_file_new && ! touch($this->_file_path.$session_id)) ? $this->_failure : $this->_success; } if ( ! $this->_file_new) { ftruncate($this->_file_handle, 0); rewind($this->_file_handle); } if (($length = strlen($session_data)) > 0) { for ($written = 0; $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 $this->_failure; } } $this->_fingerprint = md5($session_data); return $this->_success; } // ------------------------------------------------------------------------ /** * Close * * Releases locks and closes file descriptor. * * @return bool */ 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 = $this->_session_id = NULL; } return $this->_success; } // ------------------------------------------------------------------------ /** * Destroy * * Destroys the current session. * * @param string $session_id Session ID * @return bool */ public function destroy($session_id) { if ($this->close() === $this->_success) { if (file_exists($this->_file_path.$session_id)) { $this->_cookie_destroy(); return unlink($this->_file_path.$session_id) ? $this->_success : $this->_failure; } return $this->_success; } elseif ($this->_file_path !== NULL) { clearstatcache(); if (file_exists($this->_file_path.$session_id)) { $this->_cookie_destroy(); return unlink($this->_file_path.$session_id) ? $this->_success : $this->_failure; } return $this->_success; } return $this->_failure; } // ------------------------------------------------------------------------ /** * Garbage Collector * * Deletes expired sessions * * @param int $maxlifetime Maximum lifetime of sessions * @return bool */ public function gc($maxlifetime) { if ( ! is_dir($this->_config['save_path']) OR ($directory = opendir($this->_config['save_path'])) === FALSE) { log_message('debug', "Session: Garbage collector couldn't list files under directory '".$this->_config['save_path']."'."); return $this->_failure; } $ts = time() - $maxlifetime; $pattern = ($this->_config['match_ip'] === TRUE) ? '[0-9a-f]{32}' : ''; $pattern = sprintf( '#\A%s'.$pattern.$this->_sid_regexp.'\z#', preg_quote($this->_config['cookie_name']) ); while (($file = readdir($directory)) !== FALSE) { // If the filename doesn't match this pattern, it's either not a session file or is not ours if ( ! preg_match($pattern, $file) OR ! is_file($this->_config['save_path'].DIRECTORY_SEPARATOR.$file) OR ($mtime = filemtime($this->_config['save_path'].DIRECTORY_SEPARATOR.$file)) === FALSE OR $mtime > $ts) { continue; } unlink($this->_config['save_path'].DIRECTORY_SEPARATOR.$file); } closedir($directory); return $this->_success; } // -------------------------------------------------------------------- /** * Update Timestamp * * Update session timestamp without modifying data * * @param string $id Session ID * @param string $data Unknown & unused * @return bool */ public function updateTimestamp($id, $unknown) { return touch($this->_file_path.$id); } // -------------------------------------------------------------------- /** * Validate ID * * Checks whether a session ID record exists server-side, * to enforce session.use_strict_mode. * * @param string $id Session ID * @return bool */ public function validateId($id) { $result = is_file($this->_file_path.$id); clearstatcache(TRUE, $this->_file_path.$id); return $result; } // -------------------------------------------------------------------- /** * Byte-safe strlen() * * @param string $str * @return int */ protected static function strlen($str) { return (self::$func_overload) ? mb_strlen($str, '8bit') : strlen($str); } } PKw\( index.htmlnu[ 403 Forbidden

Directory access is forbidden.

PKw\6"-0-0Session_redis_driver.phpnu[=')) { $this->_setTimeout_name = 'expire'; $this->_delete_name = 'del'; $this->_ping_success = TRUE; } else { $this->_setTimeout_name = 'setTimeout'; $this->_delete_name = 'delete'; $this->_ping_success = '+PONG'; } if (empty($this->_config['save_path'])) { log_message('error', 'Session: No Redis save path configured.'); } elseif (preg_match('#(?:tcp://)?([^:?]+)(?:\:(\d+))?(\?.+)?#', $this->_config['save_path'], $matches)) { isset($matches[3]) OR $matches[3] = ''; // Just to avoid undefined index notices below $this->_config['save_path'] = array( 'host' => $matches[1], 'port' => empty($matches[2]) ? NULL : $matches[2], 'password' => preg_match('#auth=([^\s&]+)#', $matches[3], $match) ? $match[1] : NULL, 'database' => preg_match('#database=(\d+)#', $matches[3], $match) ? (int) $match[1] : NULL, 'timeout' => preg_match('#timeout=(\d+\.\d+)#', $matches[3], $match) ? (float) $match[1] : NULL ); preg_match('#prefix=([^\s&]+)#', $matches[3], $match) && $this->_key_prefix = $match[1]; } else { log_message('error', 'Session: Invalid Redis save path format: '.$this->_config['save_path']); } if ($this->_config['match_ip'] === TRUE) { $this->_key_prefix .= $_SERVER['REMOTE_ADDR'].':'; } } // ------------------------------------------------------------------------ /** * Open * * Sanitizes save_path and initializes connection. * * @param string $save_path Server path * @param string $name Session cookie name, unused * @return bool */ public function open($save_path, $name) { if (empty($this->_config['save_path'])) { return $this->_failure; } $redis = new Redis(); if ( ! $redis->connect($this->_config['save_path']['host'], $this->_config['save_path']['port'], $this->_config['save_path']['timeout'])) { log_message('error', 'Session: Unable to connect to Redis with the configured settings.'); } elseif (isset($this->_config['save_path']['password']) && ! $redis->auth($this->_config['save_path']['password'])) { log_message('error', 'Session: Unable to authenticate to Redis instance.'); } elseif (isset($this->_config['save_path']['database']) && ! $redis->select($this->_config['save_path']['database'])) { log_message('error', 'Session: Unable to select Redis database with index '.$this->_config['save_path']['database']); } else { $this->_redis = $redis; $this->php5_validate_id(); return $this->_success; } return $this->_failure; } // ------------------------------------------------------------------------ /** * Read * * Reads session data and acquires a lock * * @param string $session_id Session ID * @return string Serialized session data */ public function read($session_id) { if (isset($this->_redis) && $this->_get_lock($session_id)) { // Needed by write() to detect session_regenerate_id() calls $this->_session_id = $session_id; $session_data = $this->_redis->get($this->_key_prefix.$session_id); is_string($session_data) ? $this->_key_exists = TRUE : $session_data = ''; $this->_fingerprint = md5($session_data); return $session_data; } return $this->_failure; } // ------------------------------------------------------------------------ /** * Write * * Writes (create / update) session data * * @param string $session_id Session ID * @param string $session_data Serialized session data * @return bool */ public function write($session_id, $session_data) { if ( ! isset($this->_redis, $this->_lock_key)) { return $this->_failure; } // Was the ID regenerated? elseif ($session_id !== $this->_session_id) { if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) { return $this->_failure; } $this->_key_exists = FALSE; $this->_session_id = $session_id; } $this->_redis->{$this->_setTimeout_name}($this->_lock_key, 300); if ($this->_fingerprint !== ($fingerprint = md5($session_data)) OR $this->_key_exists === FALSE) { if ($this->_redis->set($this->_key_prefix.$session_id, $session_data, $this->_config['expiration'])) { $this->_fingerprint = $fingerprint; $this->_key_exists = TRUE; return $this->_success; } return $this->_failure; } return ($this->_redis->{$this->_setTimeout_name}($this->_key_prefix.$session_id, $this->_config['expiration'])) ? $this->_success : $this->_failure; } // ------------------------------------------------------------------------ /** * Close * * Releases locks and closes connection. * * @return bool */ public function close() { if (isset($this->_redis)) { try { if ($this->_redis->ping() === $this->_ping_success) { $this->_release_lock(); if ($this->_redis->close() === FALSE) { return $this->_failure; } } } catch (RedisException $e) { log_message('error', 'Session: Got RedisException on close(): '.$e->getMessage()); } $this->_redis = NULL; return $this->_success; } return $this->_success; } // ------------------------------------------------------------------------ /** * Destroy * * Destroys the current session. * * @param string $session_id Session ID * @return bool */ public function destroy($session_id) { if (isset($this->_redis, $this->_lock_key)) { if (($result = $this->_redis->{$this->_delete_name}($this->_key_prefix.$session_id)) !== 1) { log_message('debug', 'Session: Redis::'.$this->_delete_name.'() expected to return 1, got '.var_export($result, TRUE).' instead.'); } $this->_cookie_destroy(); return $this->_success; } return $this->_failure; } // ------------------------------------------------------------------------ /** * Garbage Collector * * Deletes expired sessions * * @param int $maxlifetime Maximum lifetime of sessions * @return bool */ public function gc($maxlifetime) { // Not necessary, Redis takes care of that. return $this->_success; } // -------------------------------------------------------------------- /** * Update Timestamp * * Update session timestamp without modifying data * * @param string $id Session ID * @param string $data Unknown & unused * @return bool */ public function updateTimestamp($id, $unknown) { return $this->_redis->{$this->_setTimeout_name}($this->_key_prefix.$id, $this->_config['expiration']); } // -------------------------------------------------------------------- /** * Validate ID * * Checks whether a session ID record exists server-side, * to enforce session.use_strict_mode. * * @param string $id Session ID * @return bool */ public function validateId($id) { return (bool) $this->_redis->exists($this->_key_prefix.$id); } // ------------------------------------------------------------------------ /** * Get lock * * Acquires an (emulated) lock. * * @param string $session_id Session ID * @return bool */ protected function _get_lock($session_id) { // PHP 7 reuses the SessionHandler object on regeneration, // so we need to check here if the lock key is for the // correct session ID. if ($this->_lock_key === $this->_key_prefix.$session_id.':lock') { return $this->_redis->{$this->_setTimeout_name}($this->_lock_key, 300); } // 30 attempts to obtain a lock, in case another request already has it $lock_key = $this->_key_prefix.$session_id.':lock'; $attempt = 0; do { if (($ttl = $this->_redis->ttl($lock_key)) > 0) { sleep(1); continue; } if ($ttl === -2 && ! $this->_redis->set($lock_key, time(), array('nx', 'ex' => 300))) { // Sleep for 1s to wait for lock releases. sleep(1); continue; } elseif ( ! $this->_redis->setex($lock_key, 300, time())) { log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id); return FALSE; } $this->_lock_key = $lock_key; break; } while (++$attempt < 30); if ($attempt === 30) { log_message('error', 'Session: Unable to obtain lock for '.$this->_key_prefix.$session_id.' after 30 attempts, aborting.'); return FALSE; } elseif ($ttl === -1) { log_message('debug', 'Session: Lock for '.$this->_key_prefix.$session_id.' had no TTL, overriding.'); } $this->_lock = TRUE; return TRUE; } // ------------------------------------------------------------------------ /** * Release lock * * Releases a previously acquired lock * * @return bool */ protected function _release_lock() { if (isset($this->_redis, $this->_lock_key) && $this->_lock) { if ( ! $this->_redis->{$this->_delete_name}($this->_lock_key)) { log_message('error', 'Session: Error while trying to free lock for '.$this->_lock_key); return FALSE; } $this->_lock_key = NULL; $this->_lock = FALSE; } return TRUE; } } PKw\})})Session_memcached_driver.phpnu[_config['save_path'])) { log_message('error', 'Session: No Memcached save path configured.'); } if ($this->_config['match_ip'] === TRUE) { $this->_key_prefix .= $_SERVER['REMOTE_ADDR'].':'; } } // ------------------------------------------------------------------------ /** * Open * * Sanitizes save_path and initializes connections. * * @param string $save_path Server path(s) * @param string $name Session cookie name, unused * @return bool */ public function open($save_path, $name) { $this->_memcached = new Memcached(); $this->_memcached->setOption(Memcached::OPT_BINARY_PROTOCOL, TRUE); // required for touch() usage $server_list = array(); foreach ($this->_memcached->getServerList() as $server) { $server_list[] = $server['host'].':'.$server['port']; } if ( ! preg_match_all('#,?([^,:]+)\:(\d{1,5})(?:\:(\d+))?#', $this->_config['save_path'], $matches, PREG_SET_ORDER)) { $this->_memcached = NULL; log_message('error', 'Session: Invalid Memcached save path format: '.$this->_config['save_path']); return $this->_failure; } foreach ($matches as $match) { // If Memcached already has this server (or if the port is invalid), skip it if (in_array($match[1].':'.$match[2], $server_list, TRUE)) { log_message('debug', 'Session: Memcached server pool already has '.$match[1].':'.$match[2]); continue; } if ( ! $this->_memcached->addServer($match[1], $match[2], isset($match[3]) ? $match[3] : 0)) { log_message('error', 'Could not add '.$match[1].':'.$match[2].' to Memcached server pool.'); } else { $server_list[] = $match[1].':'.$match[2]; } } if (empty($server_list)) { log_message('error', 'Session: Memcached server pool is empty.'); return $this->_failure; } $this->php5_validate_id(); return $this->_success; } // ------------------------------------------------------------------------ /** * Read * * Reads session data and acquires a lock * * @param string $session_id Session ID * @return string Serialized session data */ public function read($session_id) { if (isset($this->_memcached) && $this->_get_lock($session_id)) { // Needed by write() to detect session_regenerate_id() calls $this->_session_id = $session_id; $session_data = (string) $this->_memcached->get($this->_key_prefix.$session_id); $this->_fingerprint = md5($session_data); return $session_data; } return $this->_failure; } // ------------------------------------------------------------------------ /** * Write * * Writes (create / update) session data * * @param string $session_id Session ID * @param string $session_data Serialized session data * @return bool */ public function write($session_id, $session_data) { if ( ! isset($this->_memcached, $this->_lock_key)) { return $this->_failure; } // Was the ID regenerated? elseif ($session_id !== $this->_session_id) { if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) { return $this->_failure; } $this->_fingerprint = md5(''); $this->_session_id = $session_id; } $key = $this->_key_prefix.$session_id; $this->_memcached->replace($this->_lock_key, time(), 300); if ($this->_fingerprint !== ($fingerprint = md5($session_data))) { if ($this->_memcached->set($key, $session_data, $this->_config['expiration'])) { $this->_fingerprint = $fingerprint; return $this->_success; } return $this->_failure; } elseif ( $this->_memcached->touch($key, $this->_config['expiration']) OR ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND && $this->_memcached->set($key, $session_data, $this->_config['expiration'])) ) { return $this->_success; } return $this->_failure; } // ------------------------------------------------------------------------ /** * Close * * Releases locks and closes connection. * * @return bool */ public function close() { if (isset($this->_memcached)) { $this->_release_lock(); if ( ! $this->_memcached->quit()) { return $this->_failure; } $this->_memcached = NULL; return $this->_success; } return $this->_failure; } // ------------------------------------------------------------------------ /** * Destroy * * Destroys the current session. * * @param string $session_id Session ID * @return bool */ public function destroy($session_id) { if (isset($this->_memcached, $this->_lock_key)) { $this->_memcached->delete($this->_key_prefix.$session_id); $this->_cookie_destroy(); return $this->_success; } return $this->_failure; } // ------------------------------------------------------------------------ /** * Garbage Collector * * Deletes expired sessions * * @param int $maxlifetime Maximum lifetime of sessions * @return bool */ public function gc($maxlifetime) { // Not necessary, Memcached takes care of that. return $this->_success; } // -------------------------------------------------------------------- /** * Update Timestamp * * Update session timestamp without modifying data * * @param string $id Session ID * @param string $data Unknown & unused * @return bool */ public function updateTimestamp($id, $unknown) { return $this->_memcached->touch($this->_key_prefix.$id, $this->_config['expiration']); } // -------------------------------------------------------------------- /** * Validate ID * * Checks whether a session ID record exists server-side, * to enforce session.use_strict_mode. * * @param string $id Session ID * @return bool */ public function validateId($id) { $this->_memcached->get($this->_key_prefix.$id); return ($this->_memcached->getResultCode() === Memcached::RES_SUCCESS); } // ------------------------------------------------------------------------ /** * Get lock * * Acquires an (emulated) lock. * * @param string $session_id Session ID * @return bool */ protected function _get_lock($session_id) { // PHP 7 reuses the SessionHandler object on regeneration, // so we need to check here if the lock key is for the // correct session ID. if ($this->_lock_key === $this->_key_prefix.$session_id.':lock') { if ( ! $this->_memcached->replace($this->_lock_key, time(), 300)) { return ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND) ? $this->_memcached->add($this->_lock_key, time(), 300) : FALSE; } return TRUE; } // 30 attempts to obtain a lock, in case another request already has it $lock_key = $this->_key_prefix.$session_id.':lock'; $attempt = 0; do { if ($this->_memcached->get($lock_key)) { sleep(1); continue; } $method = ($this->_memcached->getResultCode() === Memcached::RES_NOTFOUND) ? 'add' : 'set'; if ( ! $this->_memcached->$method($lock_key, time(), 300)) { log_message('error', 'Session: Error while trying to obtain lock for '.$this->_key_prefix.$session_id); return FALSE; } $this->_lock_key = $lock_key; break; } while (++$attempt < 30); if ($attempt === 30) { log_message('error', 'Session: Unable to obtain lock for '.$this->_key_prefix.$session_id.' after 30 attempts, aborting.'); return FALSE; } $this->_lock = TRUE; return TRUE; } // ------------------------------------------------------------------------ /** * Release lock * * Releases a previously acquired lock * * @return bool */ protected function _release_lock() { if (isset($this->_memcached, $this->_lock_key) && $this->_lock) { if ( ! $this->_memcached->delete($this->_lock_key) && $this->_memcached->getResultCode() !== Memcached::RES_NOTFOUND) { log_message('error', 'Session: Error while trying to free lock for '.$this->_lock_key); return FALSE; } $this->_lock_key = NULL; $this->_lock = FALSE; } return TRUE; } } PKw\7d.d.Session_database_driver.phpnu[db) OR $CI->load->database(); $this->_db = $CI->db; if ( ! $this->_db instanceof CI_DB_query_builder) { throw new Exception('Query Builder not enabled for the configured database. Aborting.'); } elseif ($this->_db->pconnect) { throw new Exception('Configured database connection is persistent. Aborting.'); } elseif ($this->_db->cache_on) { throw new Exception('Configured database connection has cache enabled. Aborting.'); } $db_driver = $this->_db->dbdriver.(empty($this->_db->subdriver) ? '' : '_'.$this->_db->subdriver); if (strpos($db_driver, 'mysql') !== FALSE) { $this->_platform = 'mysql'; } elseif (in_array($db_driver, array('postgre', 'pdo_pgsql'), TRUE)) { $this->_platform = 'postgre'; } // Note: BC work-around for the old 'sess_table_name' setting, should be removed in the future. if ( ! isset($this->_config['save_path']) && ($this->_config['save_path'] = config_item('sess_table_name'))) { log_message('debug', 'Session: "sess_save_path" is empty; using BC fallback to "sess_table_name".'); } } // ------------------------------------------------------------------------ /** * Open * * Initializes the database connection * * @param string $save_path Table name * @param string $name Session cookie name, unused * @return bool */ public function open($save_path, $name) { if (empty($this->_db->conn_id) && ! $this->_db->db_connect()) { return $this->_failure; } $this->php5_validate_id(); return $this->_success; } // ------------------------------------------------------------------------ /** * Read * * Reads session data and acquires a lock * * @param string $session_id Session ID * @return string Serialized session data */ public function read($session_id) { if ($this->_get_lock($session_id) === FALSE) { return $this->_failure; } // Prevent previous QB calls from messing with our queries $this->_db->reset_query(); // Needed by write() to detect session_regenerate_id() calls $this->_session_id = $session_id; $this->_db ->select('data') ->from($this->_config['save_path']) ->where('id', $session_id); if ($this->_config['match_ip']) { $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); } if ( ! ($result = $this->_db->get()) OR ($result = $result->row()) === NULL) { // PHP7 will reuse the same SessionHandler object after // ID regeneration, so we need to explicitly set this to // FALSE instead of relying on the default ... $this->_row_exists = FALSE; $this->_fingerprint = md5(''); return ''; } // PostgreSQL's variant of a BLOB datatype is Bytea, which is a // PITA to work with, so we use base64-encoded data in a TEXT // field instead. $result = ($this->_platform === 'postgre') ? base64_decode(rtrim($result->data)) : $result->data; $this->_fingerprint = md5($result); $this->_row_exists = TRUE; return $result; } // ------------------------------------------------------------------------ /** * Write * * Writes (create / update) session data * * @param string $session_id Session ID * @param string $session_data Serialized session data * @return bool */ public function write($session_id, $session_data) { // Prevent previous QB calls from messing with our queries $this->_db->reset_query(); // Was the ID regenerated? if (isset($this->_session_id) && $session_id !== $this->_session_id) { if ( ! $this->_release_lock() OR ! $this->_get_lock($session_id)) { return $this->_failure; } $this->_row_exists = FALSE; $this->_session_id = $session_id; } elseif ($this->_lock === FALSE) { return $this->_failure; } if ($this->_row_exists === FALSE) { $insert_data = array( 'id' => $session_id, 'ip_address' => $_SERVER['REMOTE_ADDR'], 'timestamp' => time(), 'data' => ($this->_platform === 'postgre' ? base64_encode($session_data) : $session_data) ); if ($this->_db->insert($this->_config['save_path'], $insert_data)) { $this->_fingerprint = md5($session_data); $this->_row_exists = TRUE; return $this->_success; } return $this->_failure; } $this->_db->where('id', $session_id); if ($this->_config['match_ip']) { $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); } $update_data = array('timestamp' => time()); if ($this->_fingerprint !== md5($session_data)) { $update_data['data'] = ($this->_platform === 'postgre') ? base64_encode($session_data) : $session_data; } if ($this->_db->update($this->_config['save_path'], $update_data)) { $this->_fingerprint = md5($session_data); return $this->_success; } return $this->_failure; } // ------------------------------------------------------------------------ /** * Close * * Releases locks * * @return bool */ public function close() { return ($this->_lock && ! $this->_release_lock()) ? $this->_failure : $this->_success; } // ------------------------------------------------------------------------ /** * Destroy * * Destroys the current session. * * @param string $session_id Session ID * @return bool */ public function destroy($session_id) { if ($this->_lock) { // Prevent previous QB calls from messing with our queries $this->_db->reset_query(); $this->_db->where('id', $session_id); if ($this->_config['match_ip']) { $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); } if ( ! $this->_db->delete($this->_config['save_path'])) { return $this->_failure; } } if ($this->close() === $this->_success) { $this->_cookie_destroy(); return $this->_success; } return $this->_failure; } // ------------------------------------------------------------------------ /** * Garbage Collector * * Deletes expired sessions * * @param int $maxlifetime Maximum lifetime of sessions * @return bool */ public function gc($maxlifetime) { // Prevent previous QB calls from messing with our queries $this->_db->reset_query(); return ($this->_db->delete($this->_config['save_path'], 'timestamp < '.(time() - $maxlifetime))) ? $this->_success : $this->_failure; } // -------------------------------------------------------------------- /** * Update Timestamp * * Update session timestamp without modifying data * * @param string $id Session ID * @param string $data Unknown & unused * @return bool */ public function updateTimestamp($id, $unknown) { // Prevent previous QB calls from messing with our queries $this->_db->reset_query(); $this->_db->where('id', $id); if ($this->_config['match_ip']) { $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); } return (bool) $this->_db->update($this->_config['save_path'], array('timestamp' => time())); } // -------------------------------------------------------------------- /** * Validate ID * * Checks whether a session ID record exists server-side, * to enforce session.use_strict_mode. * * @param string $id Session ID * @return bool */ public function validateId($id) { // Prevent previous QB calls from messing with our queries $this->_db->reset_query(); $this->_db->select('1')->from($this->_config['save_path'])->where('id', $id); empty($this->_config['match_ip']) OR $this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']); $result = $this->_db->get(); empty($result) OR $result = $result->row(); return ! empty($result); } // ------------------------------------------------------------------------ /** * Get lock * * Acquires a lock, depending on the underlying platform. * * @param string $session_id Session ID * @return bool */ protected function _get_lock($session_id) { if ($this->_platform === 'mysql') { $arg = md5($session_id.($this->_config['match_ip'] ? '_'.$_SERVER['REMOTE_ADDR'] : '')); if ($this->_db->query("SELECT GET_LOCK('".$arg."', 300) AS ci_session_lock")->row()->ci_session_lock) { $this->_lock = $arg; return TRUE; } return FALSE; } elseif ($this->_platform === 'postgre') { $arg = "hashtext('".$session_id."')".($this->_config['match_ip'] ? ", hashtext('".$_SERVER['REMOTE_ADDR']."')" : ''); if ($this->_db->simple_query('SELECT pg_advisory_lock('.$arg.')')) { $this->_lock = $arg; return TRUE; } return FALSE; } return parent::_get_lock($session_id); } // ------------------------------------------------------------------------ /** * Release lock * * Releases a previously acquired lock * * @return bool */ protected function _release_lock() { if ( ! $this->_lock) { return TRUE; } if ($this->_platform === 'mysql') { if ($this->_db->query("SELECT RELEASE_LOCK('".$this->_lock."') AS ci_session_lock")->row()->ci_session_lock) { $this->_lock = FALSE; return TRUE; } return FALSE; } elseif ($this->_platform === 'postgre') { if ($this->_db->simple_query('SELECT pg_advisory_unlock('.$this->_lock.')')) { $this->_lock = FALSE; return TRUE; } return FALSE; } return parent::_release_lock(); } } PK$5\!Cache_file.phpnu[load->helper('file'); $path = $CI->config->item('cache_path'); $this->_cache_path = ($path === '') ? APPPATH.'cache/' : $path; } // ------------------------------------------------------------------------ /** * Fetch from cache * * @param string $id Cache ID * @return mixed Data on success, FALSE on failure */ public function get($id) { $data = $this->_get($id); return is_array($data) ? $data['data'] : FALSE; } // ------------------------------------------------------------------------ /** * Save into cache * * @param string $id Cache ID * @param mixed $data Data to store * @param int $ttl Time to live in seconds * @param bool $raw Whether to store the raw value (unused) * @return bool TRUE on success, FALSE on failure */ public function save($id, $data, $ttl = 60, $raw = FALSE) { $contents = array( 'time' => time(), 'ttl' => $ttl, 'data' => $data ); if (write_file($this->_cache_path.$id, serialize($contents))) { chmod($this->_cache_path.$id, 0640); return TRUE; } return FALSE; } // ------------------------------------------------------------------------ /** * Delete from Cache * * @param mixed unique identifier of item in cache * @return bool true on success/false on failure */ public function delete($id) { return is_file($this->_cache_path.$id) ? unlink($this->_cache_path.$id) : FALSE; } // ------------------------------------------------------------------------ /** * Increment a raw value * * @param string $id Cache ID * @param int $offset Step/value to add * @return New value on success, FALSE on failure */ public function increment($id, $offset = 1) { $data = $this->_get($id); if ($data === FALSE) { $data = array('data' => 0, 'ttl' => 60); } elseif ( ! is_int($data['data'])) { return FALSE; } $new_value = $data['data'] + $offset; return $this->save($id, $new_value, $data['ttl']) ? $new_value : FALSE; } // ------------------------------------------------------------------------ /** * Decrement a raw value * * @param string $id Cache ID * @param int $offset Step/value to reduce by * @return New value on success, FALSE on failure */ public function decrement($id, $offset = 1) { $data = $this->_get($id); if ($data === FALSE) { $data = array('data' => 0, 'ttl' => 60); } elseif ( ! is_int($data['data'])) { return FALSE; } $new_value = $data['data'] - $offset; return $this->save($id, $new_value, $data['ttl']) ? $new_value : FALSE; } // ------------------------------------------------------------------------ /** * Clean the Cache * * @return bool false on failure/true on success */ public function clean() { return delete_files($this->_cache_path, FALSE, TRUE); } // ------------------------------------------------------------------------ /** * Cache Info * * Not supported by file-based caching * * @param string user/filehits * @return mixed FALSE */ public function cache_info($type = NULL) { return get_dir_file_info($this->_cache_path); } // ------------------------------------------------------------------------ /** * Get Cache Metadata * * @param mixed key to get cache metadata on * @return mixed FALSE on failure, array on success. */ public function get_metadata($id) { if ( ! is_file($this->_cache_path.$id)) { return FALSE; } $data = unserialize(file_get_contents($this->_cache_path.$id)); if (is_array($data)) { $mtime = filemtime($this->_cache_path.$id); if ( ! isset($data['ttl'], $data['time'])) { return FALSE; } return array( 'expire' => $data['time'] + $data['ttl'], 'mtime' => $mtime ); } return FALSE; } // ------------------------------------------------------------------------ /** * Is supported * * In the file driver, check to see that the cache directory is indeed writable * * @return bool */ public function is_supported() { return is_really_writable($this->_cache_path); } // ------------------------------------------------------------------------ /** * Get all data * * Internal method to get all the relevant data about a cache item * * @param string $id Cache ID * @return mixed Data array on success or FALSE on failure */ protected function _get($id) { if ( ! is_file($this->_cache_path.$id)) { return FALSE; } $data = unserialize(file_get_contents($this->_cache_path.$id)); if ($data['ttl'] > 0 && time() > $data['time'] + $data['ttl']) { file_exists($this->_cache_path.$id) && unlink($this->_cache_path.$id); return FALSE; } return $data; } } PK$5\  Cache_wincache.phpnu[is_supported()) { log_message('error', 'Cache: Failed to initialize Wincache; extension not loaded/enabled?'); } } // ------------------------------------------------------------------------ /** * Get * * Look for a value in the cache. If it exists, return the data, * if not, return FALSE * * @param string $id Cache Ide * @return mixed Value that is stored/FALSE on failure */ public function get($id) { $success = FALSE; $data = wincache_ucache_get($id, $success); // Success returned by reference from wincache_ucache_get() return ($success) ? $data : FALSE; } // ------------------------------------------------------------------------ /** * Cache Save * * @param string $id Cache ID * @param mixed $data Data to store * @param int $ttl Time to live (in seconds) * @param bool $raw Whether to store the raw value (unused) * @return bool true on success/false on failure */ public function save($id, $data, $ttl = 60, $raw = FALSE) { return wincache_ucache_set($id, $data, $ttl); } // ------------------------------------------------------------------------ /** * Delete from Cache * * @param mixed unique identifier of the item in the cache * @return bool true on success/false on failure */ public function delete($id) { return wincache_ucache_delete($id); } // ------------------------------------------------------------------------ /** * Increment a raw value * * @param string $id Cache ID * @param int $offset Step/value to add * @return mixed New value on success or FALSE on failure */ public function increment($id, $offset = 1) { $success = FALSE; $value = wincache_ucache_inc($id, $offset, $success); return ($success === TRUE) ? $value : FALSE; } // ------------------------------------------------------------------------ /** * Decrement a raw value * * @param string $id Cache ID * @param int $offset Step/value to reduce by * @return mixed New value on success or FALSE on failure */ public function decrement($id, $offset = 1) { $success = FALSE; $value = wincache_ucache_dec($id, $offset, $success); return ($success === TRUE) ? $value : FALSE; } // ------------------------------------------------------------------------ /** * Clean the cache * * @return bool false on failure/true on success */ public function clean() { return wincache_ucache_clear(); } // ------------------------------------------------------------------------ /** * Cache Info * * @return mixed array on success, false on failure */ public function cache_info() { return wincache_ucache_info(TRUE); } // ------------------------------------------------------------------------ /** * Get Cache Metadata * * @param mixed key to get cache metadata on * @return mixed array on success/false on failure */ public function get_metadata($id) { if ($stored = wincache_ucache_info(FALSE, $id)) { $age = $stored['ucache_entries'][1]['age_seconds']; $ttl = $stored['ucache_entries'][1]['ttl_seconds']; $hitcount = $stored['ucache_entries'][1]['hitcount']; return array( 'expire' => $ttl - $age, 'hitcount' => $hitcount, 'age' => $age, 'ttl' => $ttl ); } return FALSE; } // ------------------------------------------------------------------------ /** * is_supported() * * Check to see if WinCache is available on this system, bail if it isn't. * * @return bool */ public function is_supported() { return (extension_loaded('wincache') && ini_get('wincache.ucenabled')); } } PK$5\88Cache_dummy.phpnu[Cache_redis.phpnu[ * @link */ class CI_Cache_redis extends CI_Driver { /** * Default config * * @static * @var array */ protected static $_default_config = array( 'socket_type' => 'tcp', 'host' => '127.0.0.1', 'password' => NULL, 'port' => 6379, 'timeout' => 0 ); /** * Redis connection * * @var Redis */ protected $_redis; /** * An internal cache for storing keys of serialized values. * * @var array */ protected $_serialized = array(); /** * del()/delete() method name depending on phpRedis version * * @var string */ protected static $_delete_name; /** * sRem()/sRemove() method name depending on phpRedis version * * @var string */ protected static $_sRemove_name; // ------------------------------------------------------------------------ /** * Class constructor * * Setup Redis * * Loads Redis config file if present. Will halt execution * if a Redis connection can't be established. * * @return void * @see Redis::connect() */ public function __construct() { if ( ! $this->is_supported()) { log_message('error', 'Cache: Failed to create Redis object; extension not loaded?'); return; } if ( ! isset(static::$_delete_name, static::$_sRemove_name)) { if (version_compare(phpversion('redis'), '5', '>=')) { static::$_delete_name = 'del'; static::$_sRemove_name = 'sRem'; } else { static::$_delete_name = 'delete'; static::$_sRemove_name = 'sRemove'; } } $CI =& get_instance(); if ($CI->config->load('redis', TRUE, TRUE)) { $config = array_merge(self::$_default_config, $CI->config->item('redis')); } else { $config = self::$_default_config; } $this->_redis = new Redis(); try { if ($config['socket_type'] === 'unix') { $success = $this->_redis->connect($config['socket']); } else // tcp socket { $success = $this->_redis->connect($config['host'], $config['port'], $config['timeout']); } if ( ! $success) { log_message('error', 'Cache: Redis connection failed. Check your configuration.'); } if (isset($config['password']) && ! $this->_redis->auth($config['password'])) { log_message('error', 'Cache: Redis authentication failed.'); } } catch (RedisException $e) { log_message('error', 'Cache: Redis connection refused ('.$e->getMessage().')'); } } // ------------------------------------------------------------------------ /** * Get cache * * @param string $key Cache ID * @return mixed */ public function get($key) { $value = $this->_redis->get($key); if ($value !== FALSE && $this->_redis->sIsMember('_ci_redis_serialized', $key)) { return unserialize($value); } return $value; } // ------------------------------------------------------------------------ /** * Save cache * * @param string $id Cache ID * @param mixed $data Data to save * @param int $ttl Time to live in seconds * @param bool $raw Whether to store the raw value (unused) * @return bool TRUE on success, FALSE on failure */ public function save($id, $data, $ttl = 60, $raw = FALSE) { if (is_array($data) OR is_object($data)) { if ( ! $this->_redis->sIsMember('_ci_redis_serialized', $id) && ! $this->_redis->sAdd('_ci_redis_serialized', $id)) { return FALSE; } isset($this->_serialized[$id]) OR $this->_serialized[$id] = TRUE; $data = serialize($data); } else { $this->_redis->{static::$_sRemove_name}('_ci_redis_serialized', $id); } return $this->_redis->set($id, $data, $ttl); } // ------------------------------------------------------------------------ /** * Delete from cache * * @param string $key Cache key * @return bool */ public function delete($key) { if ($this->_redis->{static::$_delete_name}($key) !== 1) { return FALSE; } $this->_redis->{static::$_sRemove_name}('_ci_redis_serialized', $key); return TRUE; } // ------------------------------------------------------------------------ /** * Increment a raw value * * @param string $id Cache ID * @param int $offset Step/value to add * @return mixed New value on success or FALSE on failure */ public function increment($id, $offset = 1) { return $this->_redis->incrBy($id, $offset); } // ------------------------------------------------------------------------ /** * Decrement a raw value * * @param string $id Cache ID * @param int $offset Step/value to reduce by * @return mixed New value on success or FALSE on failure */ public function decrement($id, $offset = 1) { return $this->_redis->decrBy($id, $offset); } // ------------------------------------------------------------------------ /** * Clean cache * * @return bool * @see Redis::flushDB() */ public function clean() { return $this->_redis->flushDB(); } // ------------------------------------------------------------------------ /** * Get cache driver info * * @param string $type Not supported in Redis. * Only included in order to offer a * consistent cache API. * @return array * @see Redis::info() */ public function cache_info($type = NULL) { return $this->_redis->info(); } // ------------------------------------------------------------------------ /** * Get cache metadata * * @param string $key Cache key * @return array */ public function get_metadata($key) { $value = $this->get($key); if ($value !== FALSE) { return array( 'expire' => time() + $this->_redis->ttl($key), 'data' => $value ); } return FALSE; } // ------------------------------------------------------------------------ /** * Check if Redis driver is supported * * @return bool */ public function is_supported() { return extension_loaded('redis'); } // ------------------------------------------------------------------------ /** * Class destructor * * Closes the connection to Redis if present. * * @return void */ public function __destruct() { if ($this->_redis) { $this->_redis->close(); } } } PK$5\>݂EE Cache_apc.phpnu[is_supported()) { log_message('error', 'Cache: Failed to initialize APC; extension not loaded/enabled?'); } } // ------------------------------------------------------------------------ /** * Get * * Look for a value in the cache. If it exists, return the data * if not, return FALSE * * @param string * @return mixed value that is stored/FALSE on failure */ public function get($id) { $success = FALSE; $data = apc_fetch($id, $success); return ($success === TRUE) ? $data : FALSE; } // ------------------------------------------------------------------------ /** * Cache Save * * @param string $id Cache ID * @param mixed $data Data to store * @param int $ttl Length of time (in seconds) to cache the data * @param bool $raw Whether to store the raw value (unused) * @return bool TRUE on success, FALSE on failure */ public function save($id, $data, $ttl = 60, $raw = FALSE) { return apc_store($id, $data, (int) $ttl); } // ------------------------------------------------------------------------ /** * Delete from Cache * * @param mixed unique identifier of the item in the cache * @return bool true on success/false on failure */ public function delete($id) { return apc_delete($id); } // ------------------------------------------------------------------------ /** * Increment a raw value * * @param string $id Cache ID * @param int $offset Step/value to add * @return mixed New value on success or FALSE on failure */ public function increment($id, $offset = 1) { return apc_inc($id, $offset); } // ------------------------------------------------------------------------ /** * Decrement a raw value * * @param string $id Cache ID * @param int $offset Step/value to reduce by * @return mixed New value on success or FALSE on failure */ public function decrement($id, $offset = 1) { return apc_dec($id, $offset); } // ------------------------------------------------------------------------ /** * Clean the cache * * @return bool false on failure/true on success */ public function clean() { return apc_clear_cache('user'); } // ------------------------------------------------------------------------ /** * Cache Info * * @param string user/filehits * @return mixed array on success, false on failure */ public function cache_info($type = NULL) { return apc_cache_info($type); } // ------------------------------------------------------------------------ /** * Get Cache Metadata * * @param mixed key to get cache metadata on * @return mixed array on success/false on failure */ public function get_metadata($id) { $cache_info = apc_cache_info('user', FALSE); if (empty($cache_info) OR empty($cache_info['cache_list'])) { return FALSE; } foreach ($cache_info['cache_list'] as &$entry) { if ($entry['info'] !== $id) { continue; } $success = FALSE; $metadata = array( 'expire' => ($entry['ttl'] ? $entry['mtime'] + $entry['ttl'] : 0), 'mtime' => $entry['ttl'], 'data' => apc_fetch($id, $success) ); return ($success === TRUE) ? $metadata : FALSE; } return FALSE; } // ------------------------------------------------------------------------ /** * is_supported() * * Check to see if APC is available on this system, bail if it isn't. * * @return bool */ public function is_supported() { return (extension_loaded('apc') && ini_get('apc.enabled')); } } PK$5\a,**Cache_memcached.phpnu[ array( 'host' => '127.0.0.1', 'port' => 11211, 'weight' => 1 ) ); // ------------------------------------------------------------------------ /** * Class constructor * * Setup Memcache(d) * * @return void */ public function __construct() { // Try to load memcached server info from the config file. $CI =& get_instance(); $defaults = $this->_config['default']; if ($CI->config->load('memcached', TRUE, TRUE)) { $this->_config = $CI->config->config['memcached']; } if (class_exists('Memcached', FALSE)) { $this->_memcached = new Memcached(); } elseif (class_exists('Memcache', FALSE)) { $this->_memcached = new Memcache(); } else { log_message('error', 'Cache: Failed to create Memcache(d) object; extension not loaded?'); return; } foreach ($this->_config as $cache_server) { isset($cache_server['hostname']) OR $cache_server['hostname'] = $defaults['host']; isset($cache_server['port']) OR $cache_server['port'] = $defaults['port']; isset($cache_server['weight']) OR $cache_server['weight'] = $defaults['weight']; if ($this->_memcached instanceof Memcache) { // Third parameter is persistence and defaults to TRUE. $this->_memcached->addServer( $cache_server['hostname'], $cache_server['port'], TRUE, $cache_server['weight'] ); } elseif ($this->_memcached instanceof Memcached) { $this->_memcached->addServer( $cache_server['hostname'], $cache_server['port'], $cache_server['weight'] ); } } } // ------------------------------------------------------------------------ /** * Fetch from cache * * @param string $id Cache ID * @return mixed Data on success, FALSE on failure */ public function get($id) { $data = $this->_memcached->get($id); return is_array($data) ? $data[0] : $data; } // ------------------------------------------------------------------------ /** * Save * * @param string $id Cache ID * @param mixed $data Data being cached * @param int $ttl Time to live * @param bool $raw Whether to store the raw value * @return bool TRUE on success, FALSE on failure */ public function save($id, $data, $ttl = 60, $raw = FALSE) { if ($raw !== TRUE) { $data = array($data, time(), $ttl); } if ($this->_memcached instanceof Memcached) { return $this->_memcached->set($id, $data, $ttl); } elseif ($this->_memcached instanceof Memcache) { return $this->_memcached->set($id, $data, 0, $ttl); } return FALSE; } // ------------------------------------------------------------------------ /** * Delete from Cache * * @param mixed $id key to be deleted. * @return bool true on success, false on failure */ public function delete($id) { return $this->_memcached->delete($id); } // ------------------------------------------------------------------------ /** * Increment a raw value * * @param string $id Cache ID * @param int $offset Step/value to add * @return mixed New value on success or FALSE on failure */ public function increment($id, $offset = 1) { if (($result = $this->_memcached->increment($id, $offset)) === FALSE) { return $this->_memcached->add($id, $offset) ? $offset : FALSE; } return $result; } // ------------------------------------------------------------------------ /** * Decrement a raw value * * @param string $id Cache ID * @param int $offset Step/value to reduce by * @return mixed New value on success or FALSE on failure */ public function decrement($id, $offset = 1) { if (($result = $this->_memcached->decrement($id, $offset)) === FALSE) { return $this->_memcached->add($id, 0) ? 0 : FALSE; } return $result; } // ------------------------------------------------------------------------ /** * Clean the Cache * * @return bool false on failure/true on success */ public function clean() { return $this->_memcached->flush(); } // ------------------------------------------------------------------------ /** * Cache Info * * @return mixed array on success, false on failure */ public function cache_info() { return $this->_memcached->getStats(); } // ------------------------------------------------------------------------ /** * Get Cache Metadata * * @param mixed $id key to get cache metadata on * @return mixed FALSE on failure, array on success. */ public function get_metadata($id) { $stored = $this->_memcached->get($id); if (count($stored) !== 3) { return FALSE; } list($data, $time, $ttl) = $stored; return array( 'expire' => $time + $ttl, 'mtime' => $time, 'data' => $data ); } // ------------------------------------------------------------------------ /** * Is supported * * Returns FALSE if memcached is not supported on the system. * If it is, we setup the memcached object & return TRUE * * @return bool */ public function is_supported() { return (extension_loaded('memcached') OR extension_loaded('memcache')); } // ------------------------------------------------------------------------ /** * Class destructor * * Closes the connection to Memcache(d) if present. * * @return void */ public function __destruct() { if ($this->_memcached instanceof Memcache) { $this->_memcached->close(); } elseif ($this->_memcached instanceof Memcached && method_exists($this->_memcached, 'quit')) { $this->_memcached->quit(); } } } PKw\XC--Session_files_driver.phpnu[PKw\( ]-index.htmlnu[PKw\6"-0-0.Session_redis_driver.phpnu[PKw\})})^Session_memcached_driver.phpnu[PKw\7d.d.XSession_database_driver.phpnu[PK$5\!Cache_file.phpnu[PK$5\  ^Cache_wincache.phpnu[PK$5\88Cache_dummy.phpnu[PK$5\> Cache_redis.phpnu[PK$5\>݂EE Cache_apc.phpnu[PK$5\a,**s1Cache_memcached.phpnu[PK O