You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
141 lines
4.5 KiB
141 lines
4.5 KiB
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace IOcornerstone\Framework\Services;
|
|
|
|
use IOcornerstone\Framework\GzCompression;
|
|
use IOcornerstone\Framework\Enum\CompressionMethod as Method;
|
|
|
|
/**
|
|
* @author Robert Strutts
|
|
* @copyright Copyright (c) 2022, Robert Strutts.
|
|
* @license MIT
|
|
*/
|
|
|
|
class CookieSessionsHandlerException extends \Exception {}
|
|
|
|
class CookieSessionHandler implements \SessionHandlerInterface {
|
|
public static string $cookieDomain;
|
|
public static string $cookieName = 'SES';
|
|
public static string $cookiePath = '/';
|
|
public static bool $cookieSecure = true;
|
|
public static bool $cookieHTTPOnly = true;
|
|
private $enc;
|
|
|
|
public function __construct($enc, array $options) {
|
|
if (isset($options['cookie_domain'])) {
|
|
self::$cookieDomain = $options['cookie_domain'];
|
|
} else {
|
|
self::$cookieDomain = $_SERVER['SERVER_NAME'] ?? '';
|
|
}
|
|
if (isset($options['cookie_name'])) {
|
|
self::$cookieName = $options['cookie_name'];
|
|
}
|
|
if (isset($options['cookie_path'])) {
|
|
self::$cookiePath = $options['cookie_path'];
|
|
}
|
|
if (isset($options['cookie_secure'])) {
|
|
self::$cookieSecure = $options['cookie_secure'];
|
|
} else {
|
|
/**
|
|
* @todo Fix this...use_secure
|
|
*/
|
|
$use_secure = true;
|
|
if ($use_secure === false) {
|
|
self::$cookieSecure = false;
|
|
}
|
|
}
|
|
if (isset($options['cookie_HTTP_only'])) {
|
|
self::$cookieHTTPOnly = $options['cookie_HTTP_only'];
|
|
}
|
|
if (isset($options['use_compression'])) {
|
|
self::$use_compression = $options['use_compression'];
|
|
}
|
|
if (isset($options['method'])) {
|
|
$method = $options['method'];
|
|
} else {
|
|
$method = Method::DEFLATE;
|
|
}
|
|
if (isset($options['level'])) {
|
|
$level = $options['level'];
|
|
} else {
|
|
$level = 4;
|
|
}
|
|
if (isset($options['enabled'])) {
|
|
$enabled = $options['enabled'];
|
|
} else {
|
|
$enabled = true;
|
|
}
|
|
|
|
$this->compression = new GzCompression($method, $level, $enabled);
|
|
|
|
$this->enc = $enc;
|
|
}
|
|
|
|
private function writeHelper($data): string {
|
|
$gc = $this->compression->compress($data);
|
|
if ($gc !== false) {
|
|
$data = $gc; // data is now compressed
|
|
}
|
|
if ($this->enc === false) {
|
|
return $data; // encryption is off
|
|
}
|
|
$e = $this->enc->encrypt($data);
|
|
return ($e !== false) ? $e : $data; // and encrypted
|
|
}
|
|
|
|
private function readHelper($data): string {
|
|
if ($data === null || $data === false) {
|
|
return "";
|
|
}
|
|
if ($this->enc !== false) {
|
|
$de = $this->enc->decrypt($data);
|
|
if ($de!== false) {
|
|
$data = $de; // data is now decrypted
|
|
}
|
|
}
|
|
$gd = $this->compression->decompress($data);
|
|
return ($gd !== false) ? $gd : $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::$cookieName]) ? $_COOKIE[self::$cookieName] : null;
|
|
return $this->readHelper($data) ?: "";
|
|
}
|
|
|
|
public function write($id, $data): bool {
|
|
if (headers_sent($file, $line)) {
|
|
throw new CookieSessionsHandlerException("Error headers were already sent by $file on line # $line ");
|
|
}
|
|
$data = $this->writeHelper($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 cookie_sessions_handler_exception("Session data too big (over 4KB)");
|
|
}
|
|
$cookie_lifetime = (int) ini_get('session.cookie_lifetime');
|
|
|
|
return setcookie(self::$cookieName, $data, $cookie_lifetime, self::$cookiePath, self::$cookieDomain, self::$cookieSecure, self::$cookieHTTPOnly);
|
|
}
|
|
|
|
public function destroy($id): bool {
|
|
$expiration_time = time() - 3600;
|
|
return setcookie(self::$cookieName, "", $expiration_time, self::$cookiePath, self::$cookieDomain, self::$cookieSecure, self::$cookieHTTPOnly);
|
|
}
|
|
|
|
public function gc($max_lifetime): int|false {
|
|
return 0;
|
|
}
|
|
} |