get('time_out', self::$time_out); self::$bind_ip = $config->getBool('bind_ip', self::$bind_ip); self::$guid_key = $config->get('guid_key', self::$guid_key); /* assign id from new sessions */ if (!isset($_COOKIE[self::$guid_key])) { $redis = RedisDAO::instance(); if ($redis === null) { return false; } do { // generate an unique session id self::$sid = Random::randomString(64); } while ($redis->exists('session:' . self::$sid) === 1); $redis->disconnect(); setcookie(self::$guid_key, self::$sid); } else { self::$sid = $_COOKIE[self::$guid_key]; } return true; } /* Ask browser to remember session id even if browser restarts */ public static function persist($duration) { $redis = RedisDAO::instance(); if ($redis === null) { return false; } $redis_key = 'session:' . self::$sid; $redis->expire($redis_key, $duration); $redis->disconnect(); setcookie(self::$guid_key, self::$sid, time() + $duration); return true; } /* attach session to $group to avoid wild sessions */ public static function attach($group) { $redis = RedisDAO::instance(); if ($redis === null) { return false; } $redis_key = 'session:' . self::$sid; $key = 'session-group:' . $group; $redis->sadd($key, array($redis_key)); $redis->disconnect(); return true; } /* detach session from $group */ public static function detach($group) { $redis = RedisDAO::instance(); if ($redis === null) { return false; } $key = 'session-group:' . $group; $redis_key = 'session:' . self::$sid; $redis->srem($key, $redis_key); $redis->disconnect(); return true; } /**/ public static function put($key, $value) { $redis = RedisDAO::instance(); if ($redis === null) { return false; } $redis_key = 'session:' . self::$sid; $redis->hset($redis_key, $key, $value); $redis->hset($redis_key, '_ip', cr_get_client_ip(false)); self::$cache[$key] = $value;//update cache self::get('_ip');//renew expiration $redis->disconnect(); return true; } /**/ public static function get($key, $default = null) { if (isset(self::$cache[$key])) { return self::$cache[$key]; } $redis = RedisDAO::instance(); if ($redis === null) { return $default; } $redis_key = 'session:' . self::$sid; $list = $redis->hgetall($redis_key); if (self::$bind_ip) { if (!(isset($list['_ip']) && $list['_ip'] === cr_get_client_ip(false))) { return $default; } } self::$cache = $list; if ($redis->ttl($redis_key) < self::$time_out) { $redis->expire($redis_key, self::$time_out); } $redis->disconnect(); if (isset($list[$key])) { return $list[$key]; } return $default; } /* expire current session */ public static function expire() { $redis = RedisDAO::instance(); if ($redis === null) { return false; } $redis_key = 'session:' . self::$sid; $redis->del(array($redis_key)); $redis->disconnect(); setcookie(self::$guid_key, self::$sid, time() - 3600); return true; } /**/ public static function expireByGroup($group, $index = null) { $redis = RedisDAO::instance(); if ($redis === null) { return false; } $group_key = "session-group:$group"; $keys = $redis->smembers($group_key); foreach ($keys as $i => $key) { if ($index === null || $i === $index) { $redis->srem($group_key, $key); $redis->del($key); } } $redis->disconnect(); return true; } /* Low Performance, Not recommended */ public static function listGroup(CRObject $rule) { $redis = RedisDAO::instance(); if ($redis === null) { return false; } $prefix = 'session-group:'; $keys = $redis->keys($prefix . '*'); $offset = $rule->getInt('offset', 0); $limit = $rule->getInt('limit', -1); $groups = array(); $len = strlen($prefix); foreach ($keys as $index => $key) { if ($index < $offset) { continue; } if ($limit !== -1 && $offset + $limit <= $index) { break; } $groups[] = array('index' => $index, 'group' => substr($key, $len)); } $redis->disconnect(); return $groups; } /* Low Performance, Not recommended */ public static function listSession(CRObject $rule) { $redis = RedisDAO::instance(); if ($redis === null) { return false; } $group = $rule->get('group', ''); $redis_key = "session-group:$group"; $keys = $redis->smembers($redis_key); $sessions = array(); foreach ($keys as $index => $key) { $session = $redis->hgetall($key); if (count($session) === 0) { $redis->srem($redis_key, $key); continue; } $session['_index'] = $index; $session['_current'] = $key === 'session:' . self::$sid; $sessions[] = $session; } return $sessions; } }