DigiComp.FlowSessionLock/Classes/Http/SessionLockRequestMiddleware.php

91 lines
2.7 KiB
PHP
Raw Normal View History

2021-08-26 15:05:37 +02:00
<?php
2022-05-02 09:56:10 +02:00
declare(strict_types=1);
2021-08-26 15:05:37 +02:00
namespace DigiComp\FlowSessionLock\Http;
use Neos\Flow\Annotations as Flow;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
2021-08-26 15:05:37 +02:00
use Psr\Log\LoggerInterface;
use Symfony\Component\Lock\Exception\LockAcquiringException;
2021-08-26 15:05:37 +02:00
use Symfony\Component\Lock\Key;
use Symfony\Component\Lock\LockFactory;
class SessionLockRequestMiddleware implements MiddlewareInterface
2021-08-26 15:05:37 +02:00
{
2022-03-15 09:32:42 +01:00
public const PARAMETER_NAME = 'sessionLock';
2021-08-26 15:05:37 +02:00
/**
2022-04-05 12:31:33 +02:00
* @Flow\Inject
2021-08-26 15:05:37 +02:00
* @var LoggerInterface
*/
2022-04-05 12:31:33 +02:00
protected $logger;
2021-08-26 15:05:37 +02:00
/**
* @Flow\Inject(name="DigiComp.FlowSessionLock:LockFactory")
* @var LockFactory
*/
protected $lockFactory;
/**
2022-03-15 09:32:42 +01:00
* @Flow\InjectConfiguration(package="Neos.Flow", path="session")
* @var array
*/
2022-03-15 09:32:42 +01:00
protected array $sessionSettings;
/**
* @Flow\InjectConfiguration(package="DigiComp.FlowSessionLock", path="timeToLive")
2022-03-15 09:32:42 +01:00
* @var float
*/
protected float $timeToLive;
/**
* @Flow\InjectConfiguration(package="DigiComp.FlowSessionLock", path="autoRelease")
* @var bool
*/
2022-03-15 09:32:42 +01:00
protected bool $autoRelease;
/**
* @Flow\InjectConfiguration(package="DigiComp.FlowSessionLock", path="secondsToWait")
* @var int
*/
protected int $secondsToWait;
2021-08-26 15:05:37 +02:00
/**
* @inheritDoc
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
2021-08-26 15:05:37 +02:00
{
$sessionCookieName = $this->sessionSettings['name'];
$cookies = $request->getCookieParams();
2021-08-26 15:05:37 +02:00
if (!isset($cookies[$sessionCookieName])) {
return $handler->handle($request);
2021-08-26 15:05:37 +02:00
}
2022-03-15 09:32:42 +01:00
// TODO: sessionIdentifier might be wrong, probably it should probably be storage identifier
$key = new Key('session-' . $cookies[$sessionCookieName]);
2021-08-26 15:05:37 +02:00
$lock = $this->lockFactory->createLockFromKey($key, $this->timeToLive, $this->autoRelease);
2021-08-26 15:05:37 +02:00
$request = $request->withAttribute(static::class . '.' . static::PARAMETER_NAME, $lock);
2021-08-26 15:05:37 +02:00
$this->logger->debug('SessionLock: Try to get "' . $key . '"');
$timedOut = \time() + $this->secondsToWait;
while (!$lock->acquire()) {
if (\time() >= $timedOut) {
throw new LockAcquiringException(
'Could not acquire the lock for "' . $key . '" in ' . $this->secondsToWait . ' seconds.',
1652687960
);
}
2022-05-16 12:08:39 +02:00
\usleep(100000);
}
$this->logger->debug('SessionLock: Acquired "' . $key . '"');
return $handler->handle($request);
2021-08-26 15:05:37 +02:00
}
}