Skip to content

Commit

Permalink
[BUGFIX] Fix #160: disable cHash recalculation by default
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitryd committed Sep 13, 2016
1 parent 78c6408 commit 8c5fbb6
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 12 deletions.
1 change: 1 addition & 0 deletions Classes/Configuration/ConfigurationReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class ConfigurationReader {
'fileName/defaultToHTMLsuffixOnPrev' => FALSE,
'init/appendMissingSlash' => 'ifNotFile,redirect[301]',
'init/emptySegmentValue' => '',
'init/recalculateChashIfMissing' => false,
'pagePath/spaceCharacter' => '-', // undocumented & deprecated!
);

Expand Down
57 changes: 45 additions & 12 deletions Classes/Decoder/UrlDecoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,21 @@
use DmitryDulepov\Realurl\Cache\UrlCacheEntry;
use DmitryDulepov\Realurl\Configuration\ConfigurationReader;
use DmitryDulepov\Realurl\EncodeDecoderBase;
use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Utility\ArrayUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MathUtility;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
use TYPO3\CMS\Frontend\Page\PageRepository;

/**
* This class contains URL decoder for the RealURL.
* This class contains URL decoder for the RealURL. It is singleton because the
* same instance must run in two different hooks.
*
* @package DmitryDulepov\Realurl\Decoder
* @author Dmitry Dulepov <[email protected]>
*/
class UrlDecoder extends EncodeDecoderBase {
class UrlDecoder extends EncodeDecoderBase implements SingletonInterface {

const REDIRECT_STATUS_HEADER = 'HTTP/1.0 301 TYPO3 RealURL Redirect';
const REDIRECT_INFO_HEADER = 'X-TYPO3-RealURL-Info';
Expand All @@ -56,6 +58,9 @@ class UrlDecoder extends EncodeDecoderBase {
/** @var TypoScriptFrontendController */
protected $caller;

/** @var UrlCacheEntry */
protected $createdCacheEntry = null;

/** @var int */
protected $detectedLanguageId = 0;

Expand Down Expand Up @@ -145,6 +150,35 @@ public function decodeUrl(array $params) {
}
}

/**
* Stores decoded record to the URL cache. This function is called after
* TSFE validates cHash. This way we avoid storing URLs with wrong cHash
* in the cache that would always lead to a 404 until URL cache is cleared.
*
* Currently this function uses 'configArrayPostProc' because this hook
* is closest to the TypoScriptFrontendController::makeCacheHash(). If
* execution comes here, than cHash is validated (assuming that
* $TYPO3_CONF_VARS['FE']['pageNotFoundOnCHashError'] is true). However
* it may not be the best place. Another place could be
* TypoScriptFrontendController::hook_eofe(), which runs after the content
* is generated. Advantage is that the URL to the current page could be
* already generated by the encoding process, which is guaranteed to make
* the URL correctly. On the other hand, if content generation fails for
* some reason, we will not have entries in any case and the next call
* to this URL will have to make costly decoding again. To avoid the
* problem, we do it in the earlier hook. Later, when expiration of URL
* entries is implemented, we could set expiration time for this record
* and the encoder will unexpire it if it generates the same URL. The
* advantage of this is that there will be a proper redirect and no
* duplicate content due to possibly different encoded URL.
*/
public function storeCacheRecord() {
// If it is still not there (could have been added by other process!), than store it
if ($this->createdCacheEntry && !$this->isExpiredPath && !$this->getFromUrlCache($this->speakingUri)) {
$this->putToUrlCache($this->createdCacheEntry);
}
}

/**
* Calculates and adds cHash to the entry. This function is only called
* if we had to decode the entry, which was not in the cache. Even if we
Expand All @@ -157,13 +191,15 @@ public function decodeUrl(array $params) {
*/
protected function calculateChash(UrlCacheEntry $cacheEntry) {
$requestVariables = $cacheEntry->getRequestVariables();
$cacheHashCalculator = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Page\\CacheHashCalculator');
/* @var \TYPO3\CMS\Frontend\Page\CacheHashCalculator $cacheHashCalculator */
$cHashParameters = $cacheHashCalculator->getRelevantParameters(GeneralUtility::implodeArrayForUrl('', $requestVariables));
if (!isset($requestVariables['cHash']) && $this->configuration->get('init/recalculateChashIfMissing')) {
$cacheHashCalculator = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Page\\CacheHashCalculator');
/* @var \TYPO3\CMS\Frontend\Page\CacheHashCalculator $cacheHashCalculator */
$cHashParameters = $cacheHashCalculator->getRelevantParameters(GeneralUtility::implodeArrayForUrl('', $requestVariables));

if (count($cHashParameters) > 0) {
$requestVariables['cHash'] = $cacheHashCalculator->calculateCacheHash($cHashParameters);
$cacheEntry->setRequestVariables($requestVariables);
if (count($cHashParameters) > 0) {
$requestVariables['cHash'] = $cacheHashCalculator->calculateCacheHash($cHashParameters);
$cacheEntry->setRequestVariables($requestVariables);
}
}
}

Expand Down Expand Up @@ -1263,10 +1299,7 @@ protected function runDecoding() {
$this->checkExpiration($cacheEntry);
$this->setRequestVariables($cacheEntry);

// If it is still not there (could have been added by other process!), than update
if (!$this->isExpiredPath && !$this->getFromUrlCache($this->speakingUri)) {
$this->putToUrlCache($cacheEntry);
}
$this->createdCacheEntry = $cacheEntry;
}

/**
Expand Down
1 change: 1 addition & 0 deletions ext_localconf.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ function includeRealurlConfiguration() {
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tstemplate.php']['linkData-PostProc']['realurl'] = 'DmitryDulepov\\Realurl\\Encoder\\UrlEncoder->encodeUrl';
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['typoLink_PostProc']['realurl'] = 'DmitryDulepov\\Realurl\\Encoder\\UrlEncoder->postProcessEncodedUrl';
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['checkAlternativeIdMethods-PostProc']['realurl'] = 'DmitryDulepov\\Realurl\\Decoder\\UrlDecoder->decodeUrl';
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['configArrayPostProc']['realurl'] = 'DmitryDulepov\\Realurl\\Decoder\\UrlDecoder->storeCacheRecord';

includeRealurlConfiguration();

Expand Down

0 comments on commit 8c5fbb6

Please sign in to comment.