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