use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerAwareTrait;
+use TYPO3\CMS\Core\Http\RedirectResponse;
use TYPO3\CMS\Core\Routing\PageArguments;
use TYPO3\CMS\Core\TimeTracker\TimeTracker;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* This middleware validates given request parameters against the common "cHash" functionality.
*/
-class PageArgumentValidator implements MiddlewareInterface
+class PageArgumentValidator implements MiddlewareInterface, LoggerAwareInterface
{
+ use LoggerAwareTrait;
/**
* The cHash Service class used for cHash related functionality
$queryParams = $request->getQueryParams();
}
if (!empty($queryParams) && !$this->evaluateCacheHashParameter($queryParams, $pageNotFoundOnValidationError)) {
+ // cHash was given, but nothing to be calculated, so let's do a redirect to the current page
+ // but without the cHash
+ if ($this->controller->cHash && empty($this->controller->cHash_array)) {
+ $uri = $request->getUri();
+ unset($queryParams['cHash']);
+ $uri = $uri->withQuery(HttpUtility::buildQueryString($queryParams));
+ return new RedirectResponse($uri, 308);
+ }
return GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
$request,
'Request parameters could not be validated (&cHash comparison failed)',
$queryParams['id'] = $this->controller->id;
$relevantParameters = $this->cacheHashCalculator->getRelevantParameters(HttpUtility::buildQueryString($queryParams));
$this->controller->cHash_array = $relevantParameters;
- $calculatedCacheHash = $this->cacheHashCalculator->calculateCacheHash($relevantParameters);
// cHash was given, but nothing to be calculated, so cHash is unset and all is good.
if (empty($relevantParameters)) {
- $this->getTimeTracker()->setTSlogMessage('The incoming cHash "' . $this->controller->cHash . '" is given but not needed. cHash is unset', 2);
- // We do not need to update the query params as everything is checked via $TSFE->cHash, see $TSFE->reqCHash()
- $this->controller->cHash = '';
- return true;
+ $this->logger->notice('The incoming cHash "' . $this->controller->cHash . '" is given but not needed. cHash is unset');
+ return false;
}
+ $calculatedCacheHash = $this->cacheHashCalculator->calculateCacheHash($relevantParameters);
if (!hash_equals($calculatedCacheHash, $this->controller->cHash)) {
// Early return to trigger the error controller
if ($pageNotFoundOnCacheHashError) {
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
+use Psr\Log\NullLogger;
use TYPO3\CMS\Core\Http\Response;
use TYPO3\CMS\Core\Http\ServerRequest;
use TYPO3\CMS\Core\Routing\PageArguments;
/**
* @test
*/
- public function givenCacheHashWithoutRequiredParametersIgnoresCacheHashAndUnsetsCacheHash(): void
+ public function givenCacheHashWithoutRequiredParametersTriggersRedirect(): void
{
- $incomingUrl = 'https://example.com/lotus-flower/en/mr-magpie/bloom/';
+ $incomingUrl = 'https://example.com/lotus-flower/en/mr-magpie/bloom/?cHash=XYZ';
+ $expectedResult = 'https://example.com/lotus-flower/en/mr-magpie/bloom/';
$this->controller->id = 13;
$this->controller->cHash = 'XYZ';
$request = $request->withAttribute('routing', $pageArguments);
$subject = new PageArgumentValidator($this->controller);
+ $subject->setLogger(new NullLogger());
+
$response = $subject->process($request, $this->responseOutputHandler);
- static::assertEquals(200, $response->getStatusCode());
- static::assertEquals('', $this->controller->cHash);
+ static::assertEquals(308, $response->getStatusCode());
+ static::assertEquals($expectedResult, $response->getHeader('Location')[0]);
}
/**
*/
public function givenCacheHashNotMatchingCalculatedCacheHashTriggers404(): void
{
- $incomingUrl = 'https://example.com/lotus-flower/en/mr-magpie/bloom/';
+ $incomingUrl = 'https://example.com/lotus-flower/en/mr-magpie/bloom/?cHash=YAZ';
$this->controller->id = 13;
$this->controller->cHash = 'XYZ';