parent
94364ac996
commit
3e12705ff6
@ -0,0 +1,114 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
declare(strict_types=1); |
||||||
|
|
||||||
|
namespace tts\services\sessions; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Robert Strutts <Robert@TryingToScale.com> |
||||||
|
* @copyright Copyright (c) 2022, Robert Strutts. |
||||||
|
* @license https://mit-license.org/ |
||||||
|
*/ |
||||||
|
|
||||||
|
class cookie_sessions_handler_exception extends \Exception {} |
||||||
|
|
||||||
|
class cookie_sessions implements \SessionHandlerInterface { |
||||||
|
private static int $zlib_compression_level = 4; |
||||||
|
public static string $cookie_domain; |
||||||
|
public static string $cookie_name = 'SES'; |
||||||
|
public static string $cookie_path = '/'; |
||||||
|
public static bool $cookie_secure = true; |
||||||
|
public static bool $cookie_HTTP_only = true; |
||||||
|
private $enc; |
||||||
|
|
||||||
|
public static function set_zlib_compression_level(int $level): void { |
||||||
|
self::$zlib_compression_level = ($level >= 0 && $level <= 9) ? |
||||||
|
$level : 4; |
||||||
|
} |
||||||
|
|
||||||
|
public function __construct($enc) { |
||||||
|
self::$cookie_domain = $_SERVER['SERVER_NAME'] ?? ''; |
||||||
|
$this->enc = $enc; |
||||||
|
} |
||||||
|
|
||||||
|
private function encrypt(string & $data): void { |
||||||
|
$data = $this->enc->encode("sess", $data); |
||||||
|
} |
||||||
|
|
||||||
|
private function decrypt(string & $data): void { |
||||||
|
try { |
||||||
|
$data = $this->enc->decode("sess", $data); |
||||||
|
} catch (\Exception $e) { |
||||||
|
$data = false; // Maybe it has no data to decode |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private function compress(string & $data): void { |
||||||
|
$data = gzdeflate($data, self::$zlib_compression_level); |
||||||
|
if ($data === false) { |
||||||
|
throw new \tts\services\sessions\cookie_sessions_handler_exception('Failed to compress session data'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private function decompress(string & $data): void { |
||||||
|
$data = gzinflate($data); |
||||||
|
} |
||||||
|
|
||||||
|
public function open($save_path, $session_name):bool { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public function close(): bool { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public function read($id): false|string { |
||||||
|
$data = isset($_COOKIE[self::$cookie_name]) ? $_COOKIE[self::$cookie_name] : null; |
||||||
|
if ($data === null) { |
||||||
|
return ""; |
||||||
|
} |
||||||
|
|
||||||
|
$data = base64_decode($data); |
||||||
|
if ($data === false) { |
||||||
|
return ""; |
||||||
|
} |
||||||
|
|
||||||
|
$this->decrypt($data); |
||||||
|
if ($data === false) { |
||||||
|
return ""; |
||||||
|
} |
||||||
|
|
||||||
|
$this->decompress($data); |
||||||
|
return ($data !== false) ? $data : ''; |
||||||
|
} |
||||||
|
|
||||||
|
public function write($id, $data): bool { |
||||||
|
if (headers_sent($file, $line)) { |
||||||
|
throw new \tts\services\sessions\cookie_sessions_handler_exception("Error headers were already sent by $file on line # $line "); |
||||||
|
} |
||||||
|
|
||||||
|
$this->compress($data); |
||||||
|
$this->encrypt($data); |
||||||
|
$data = base64_encode($data); |
||||||
|
/* |
||||||
|
* Google Chrome - 4096 bytes confirming to RFC. |
||||||
|
* If the data is over 4000 bytes, throw an exception |
||||||
|
* as web browsers only support up to 4K of Cookie Data! |
||||||
|
*/ |
||||||
|
if (strlen($data) > 4000) { |
||||||
|
throw new \tts\services\sessions\cookie_sessions_handler_exception("Session data too big (over 4KB)"); |
||||||
|
} |
||||||
|
$cookie_lifetime = (int) ini_get('session.cookie_lifetime'); |
||||||
|
|
||||||
|
return setcookie(self::$cookie_name, $data, $cookie_lifetime, self::$cookie_path, self::$cookie_domain, self::$cookie_secure, self::$cookie_HTTP_only); |
||||||
|
} |
||||||
|
|
||||||
|
public function destroy($id): bool { |
||||||
|
$expiration_time = time() - 3600; |
||||||
|
return setcookie(self::$cookie_name, "", $expiration_time, self::$cookie_path, self::$cookie_domain, self::$cookie_secure, self::$cookie_HTTP_only); |
||||||
|
} |
||||||
|
|
||||||
|
public function gc($max_lifetime): int|false { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
} |
||||||
@ -1,7 +0,0 @@ |
|||||||
<?php
|
|
||||||
declare(strict_types=1); |
|
||||||
?> |
|
||||||
<pre> |
|
||||||
<?= $ex ?> |
|
||||||
<?php var_dump(debug_backtrace()); ?> |
|
||||||
</pre> |
|
||||||
Loading…
Reference in new issue