Skip to content

Commit

Permalink
Merge pull request #43 from Kdyby/fixed-sessions
Browse files Browse the repository at this point in the history
Improve session handling
  • Loading branch information
fprochazka committed Feb 10, 2015
2 parents 9cbed10 + 14b0648 commit e52b2ec
Show file tree
Hide file tree
Showing 10 changed files with 523 additions and 72 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ env:
- NETTE=nette-2.2

php:
- 5.3.3
- 5.4
- 5.5
- 5.6
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Kdyby/Redis
Requirements
------------

Kdyby/Redis requires PHP 5.3.2 or higher.
Kdyby/Redis requires PHP 5.4 or higher.

- [Nette Framework](https://github.com/nette/nette)
- [Redis database](http://redis.io)
Expand Down
4 changes: 4 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"issues": "https://github.com/kdyby/redis/issues"
},
"require": {
"php": ">=5.4",
"nette/di": "~2.2@dev",
"nette/caching": "~2.2@dev",
"nette/http": "~2.2@dev",
Expand Down Expand Up @@ -59,6 +60,9 @@
"src/Kdyby/Redis/exceptions.php"
]
},
"autoload-dev": {
"classmap": ["tests/KdybyTests/Redis"]
},
"extra": {
"branch-alias": {
"dev-master": "3.2-dev"
Expand Down
2 changes: 1 addition & 1 deletion src/Kdyby/Redis/DI/RedisExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ protected function loadSession(array $config)
->setClass('Kdyby\Redis\RedisSessionHandler', array($this->prefix('@sessionHandler_client')));

$builder->getDefinition('session')
->addSetup('setStorage', array($this->prefix('@sessionHandler')));
->addSetup('setHandler', array($this->prefix('@sessionHandler')));
}
}

Expand Down
120 changes: 72 additions & 48 deletions src/Kdyby/Redis/RedisSessionHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
*
* @author Filip Procházka <[email protected]>
*/
class RedisSessionHandler extends Nette\Object implements Nette\Http\ISessionStorage
class RedisSessionHandler extends Nette\Object implements \SessionHandlerInterface
{

/** @internal cache structure */
Expand All @@ -41,6 +41,11 @@ class RedisSessionHandler extends Nette\Object implements Nette\Http\ISessionSto
*/
private $client;

/**
* @var integer
*/
private $ttl;



/**
Expand All @@ -49,61 +54,62 @@ class RedisSessionHandler extends Nette\Object implements Nette\Http\ISessionSto
public function __construct(RedisClient $redisClient)
{
$this->client = $redisClient;
$this->ttl = ini_get("session.gc_maxlifetime");
}



/**
* @param $savePath
* @param $sessionName
*
* @param int $ttl
*/
public function setTtl($ttl)
{
$this->ttl = max($ttl, 0);
}



/**
* @param string $savePath
* @param string $sessionName
* @return bool
*/
public function open($savePath, $sessionName)
{
return TRUE;
$id = &$_COOKIE[$sessionName]; // prevent notice
if (!is_string($id) || !preg_match('#^[0-9a-zA-Z,-]{22,128}\z#i', $id)) {
return FALSE; // Wtf?
}

return (bool) $this->lock($id);
}



/**
* @param string $id
*
* @throws SessionHandlerException
* @return string
*/
public function read($id)
{
try {
$key = $this->formatKey($id);
$this->ssIds[$key] = $this->client->lock($key);
return (string) $this->client->get($key);

} catch (Exception $e) {
Debugger::log($e, 'redis-session');
return FALSE;
}
return (string) $this->client->get($this->lock($id));
}



/**
* @param string $id
* @param string $data
*
* @return bool
*/
public function write($id, $data)
{
try {
$key = $this->formatKey($id);
$this->ssIds[$key] = $this->client->lock($key);
$this->client->setex($key, ini_get("session.gc_maxlifetime"), $data);
return TRUE;

} catch (Exception $e) {
Debugger::log($e, 'redis-session');
if (!isset($this->ssIds[$id])) {
return FALSE;
}

return $this->client->setex($this->formatKey($id), $this->ttl, $data);
}


Expand All @@ -113,33 +119,19 @@ public function write($id, $data)
*
* @return bool
*/
public function remove($id)
public function destroy($id)
{
try {
$key = $this->formatKey($id);
$this->client->multi(function (RedisClient $client) use ($key) {
$client->del($key);
$client->unlock($key);
});
unset($this->ssIds[$key]);
return TRUE;

} catch (Exception $e) {
Debugger::log($e, 'redis-session');
if (!isset($this->ssIds[$id])) {
return FALSE;
}
}

$key = $this->formatKey($id);
$this->client->multi(function (RedisClient $client) use ($key) {
$client->del($key);
$client->unlock($key);
});


/**
* @param string $id
*
* @return string
*/
private function formatKey($id)
{
return self::NS_NETTE . $id;
return TRUE;
}


Expand All @@ -149,7 +141,7 @@ private function formatKey($id)
*/
public function close()
{
foreach ($this->ssIds as $key => $yes) {
foreach ($this->ssIds as $id => $key) {
$this->client->unlock($key);
}
$this->ssIds = array();
Expand All @@ -164,13 +156,45 @@ public function close()
*
* @return bool
*/
public function clean($maxLifeTime)
public function gc($maxLifeTime)
{
return TRUE;
}



/**
* @param string $id
* @return string
*/
protected function lock($id)
{
try {
$key = $this->formatKey($id);
$this->client->lock($key);
$this->ssIds[$id] = $key;

return $key;

} catch (LockException $e) {
throw new SessionHandlerException(sprintf('Cannot work with non-locked session id %s: %s', $id, $e->getMessage()), 0, $e);
}
}



/**
* @param string $id
*
* @return string
*/
private function formatKey($id)
{
return self::NS_NETTE . $id;
}



public function __destruct()
{
$this->close();
Expand Down
10 changes: 10 additions & 0 deletions src/Kdyby/Redis/exceptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ class ConnectionException extends \RuntimeException implements Exception



/**
* @author Filip Procházka <[email protected]>
*/
class SessionHandlerException extends \RuntimeException implements Exception
{

}



/**
* @author Filip Procházka <[email protected]>
*/
Expand Down
Loading

0 comments on commit e52b2ec

Please sign in to comment.