Support header locking

Locking for http header. Throw exceptions. Socket shouldn't be affected
by this since these classes are http specific.
This commit is contained in:
Dennis Eichhorn 2016-03-19 12:20:44 +01:00
parent 9dd230df36
commit 09ca1a5c08
3 changed files with 106 additions and 7 deletions

View File

@ -28,6 +28,8 @@ class CookieJar
{
private $cookies = [];
private static $isLocked = false;
public function __construct()
{
$this->cookies = $_COOKIE;
@ -70,8 +72,22 @@ class CookieJar
public function save()
{
if(self::$isLocked) {
throw new \Exception('Already locked');
}
foreach ($this->cookies as $key => $cookie) {
setcookie($key, $cookie['value'], $cookie['expiry'], $cookie['path'], $cookie['domain'], $cookie['secure'], $cookie['httponly']);
}
}
public static function lock()
{
self::$isLocked = true;
}
public static function isLocked() : bool
{
return self::$isLocked;
}
}

View File

@ -41,6 +41,14 @@ class HttpSession implements SessionInterface
*/
private $sid = null;
/**
* Is session locked/already set.
*
* @var bool
* @since 1.0.0
*/
private static $isLocked = false;
/**
* Constructor.
*
@ -52,6 +60,10 @@ class HttpSession implements SessionInterface
*/
public function __construct(int $liftetime = 3600, $sid = false)
{
if(self::$isLocked) {
throw new \Exception('Already locked');
}
if (!is_bool($sid)) {
session_id($sid);
}
@ -62,6 +74,19 @@ class HttpSession implements SessionInterface
$_SESSION = null;
$this->sid = session_id();
$this->setCsrfProtection();
self::$isLocked = true;
}
/**
* Set Csrf protection for forms.
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
private function setCsrfProtection()
{
$this->set('UID', 0, false);
if(($CSRF = $this->get('CSRF')) === null) {
@ -138,4 +163,14 @@ class HttpSession implements SessionInterface
session_write_close();
}
public static function lock()
{
self::$isLocked = true;
}
public static function isLocked()
{
return self::$isLocked;
}
}

View File

@ -51,6 +51,8 @@ class Response extends ResponseAbstract implements RenderableInterface
*/
private $head = null;
private static $isLocked = false;
/**
* Constructor.
*
@ -75,9 +77,15 @@ class Response extends ResponseAbstract implements RenderableInterface
*/
public function pushHeaderId($name)
{
if(self::$isLocked) {
throw new \Exception('Already locked');
}
foreach ($this->header[$name] as $key => $value) {
header($name, $value);
}
$this->lock();
}
/**
@ -92,6 +100,10 @@ class Response extends ResponseAbstract implements RenderableInterface
*/
public function removeHeader(int $key) : bool
{
if(self::$isLocked) {
throw new \Exception('Already locked');
}
if (isset($this->header[$key])) {
unset($this->header[$key]);
@ -114,18 +126,33 @@ class Response extends ResponseAbstract implements RenderableInterface
public function generateHeader(int $code)
{
if ($code === 403) {
$this->setHeader('HTTP', 'HTTP/1.0 403 Forbidden');
$this->setHeader('Status', 'Status: HTTP/1.0 403 Forbidden');
$this->generate403();
} elseif ($code === 406) {
$this->setHeader('HTTP', 'HTTP/1.0 406 Not acceptable');
$this->setHeader('Status', 'Status:406 Not acceptable');
$this->generate406();
} elseif ($code === 503) {
$this->setHeader('HTTP', 'HTTP/1.0 503 Service Temporarily Unavailable');
$this->setHeader('Status', 'Status: 503 Service Temporarily Unavailable');
$this->setHeader('Retry-After', 'Retry-After: 300');
$this->generate503();
}
}
private function generate403()
{
$this->setHeader('HTTP', 'HTTP/1.0 403 Forbidden');
$this->setHeader('Status', 'Status: HTTP/1.0 403 Forbidden');
}
private function generate406()
{
$this->setHeader('HTTP', 'HTTP/1.0 406 Not acceptable');
$this->setHeader('Status', 'Status: 406 Not acceptable');
}
private function generate503()
{
$this->setHeader('HTTP', 'HTTP/1.0 503 Service Temporarily Unavailable');
$this->setHeader('Status', 'Status: 503 Service Temporarily Unavailable');
$this->setHeader('Retry-After', 'Retry-After: 300');
}
/**
* Set response.
*
@ -183,11 +210,17 @@ class Response extends ResponseAbstract implements RenderableInterface
*/
public function pushHeader()
{
if(self::$isLocked) {
throw new \Exception('Already locked');
}
foreach ($this->header as $name => $arr) {
foreach ($arr as $ele => $value) {
header($name . ': ' . $value);
}
}
$this->lock();
}
/**
@ -202,6 +235,10 @@ class Response extends ResponseAbstract implements RenderableInterface
*/
public function remove(int $id) : bool
{
if(self::$isLocked) {
throw new \Exception('Already locked');
}
if (isset($this->response[$id])) {
unset($this->response[$id]);
@ -335,6 +372,10 @@ class Response extends ResponseAbstract implements RenderableInterface
*/
public function setHeader($key, string $header, bool $overwrite = false) : bool
{
if(self::$isLocked) {
throw new \Exception('Already locked');
}
if (!$overwrite && isset($this->header[$key])) {
return false;
} elseif ($overwrite) {
@ -349,4 +390,11 @@ class Response extends ResponseAbstract implements RenderableInterface
return true;
}
private function lock()
{
CookieJar::lock();
HttpSession::lock();
self::$isLocked = true;
}
}