From 88122436e5eaca2e29354d41f2981f853ed8f5d9 Mon Sep 17 00:00:00 2001 From: Benni Mack <benni@typo3.org> Date: Mon, 15 Nov 2021 21:13:35 +0100 Subject: [PATCH] [BUGFIX] Make external page error handling work again In recent TYPO3 v11.5.x versions, the error handling for Frontend pages did cache the external PSR-7 Response (by guzzle) in the pages cache. However, if the error page was fetched the second time, the Response object from the cache did not have a valid stream anymore, thus resulting in an array. This change now caches the body + headers for the page (still, only when a 200 response code was returned), and re-builds a clean Response object. Resolves: #95940 Related: #95586 Related: #94402 Releases: master Change-Id: I27aaffe8acda275fd3450f9479e19a3f21d22df6 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/72184 Tested-by: core-ci <typo3@b13.com> Tested-by: Oliver Bartsch <bo@cedev.de> Tested-by: Oliver Hader <oliver.hader@typo3.org> Reviewed-by: Oliver Bartsch <bo@cedev.de> Reviewed-by: Oliver Hader <oliver.hader@typo3.org> --- .../PageContentErrorHandler.php | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/typo3/sysext/core/Classes/Error/PageErrorHandler/PageContentErrorHandler.php b/typo3/sysext/core/Classes/Error/PageErrorHandler/PageContentErrorHandler.php index e1015c9e2048..aaab8091dd23 100644 --- a/typo3/sysext/core/Classes/Error/PageErrorHandler/PageContentErrorHandler.php +++ b/typo3/sysext/core/Classes/Error/PageErrorHandler/PageContentErrorHandler.php @@ -26,6 +26,8 @@ use TYPO3\CMS\Core\Configuration\Features; use TYPO3\CMS\Core\Exception\SiteNotFoundException; use TYPO3\CMS\Core\Http\HtmlResponse; use TYPO3\CMS\Core\Http\RequestFactory; +use TYPO3\CMS\Core\Http\Response; +use TYPO3\CMS\Core\Http\Stream; use TYPO3\CMS\Core\Http\Uri; use TYPO3\CMS\Core\LinkHandling\LinkService; use TYPO3\CMS\Core\Routing\InvalidRouteArgumentsException; @@ -138,10 +140,9 @@ class PageContentErrorHandler implements PageErrorHandlerInterface protected function cachePageRequest(string $resolvedUrl, int $pageId, callable $fetcher): ResponseInterface { $cacheIdentifier = 'errorPage_' . md5($resolvedUrl); - /** @var ResponseInterface $response */ - $response = $this->cache->get($cacheIdentifier); + $responseData = $this->cache->get($cacheIdentifier); - if (!$response) { + if (!is_array($responseData)) { /** @var ResponseInterface $response */ $response = $fetcher(); $cacheTags = []; @@ -151,8 +152,23 @@ class PageContentErrorHandler implements PageErrorHandlerInterface // Cache Tag "pageId_" ensures, cache is purged when content of 404 page changes $cacheTags[] = 'pageId_' . $pageId; } - $this->cache->set($cacheIdentifier, $response, $cacheTags); + $responseData = [ + 'headers' => $response->getHeaders(), + 'body' => $response->getBody()->getContents(), + 'reasonPhrase' => $response->getReasonPhrase(), + ]; + $this->cache->set($cacheIdentifier, $responseData, $cacheTags); } + } else { + $body = new Stream('php://temp', 'wb+'); + $body->write($responseData['body'] ?? ''); + $body->rewind(); + $response = new Response( + $body, + 200, + $responseData['headers'] ?? [], + $responseData['reasonPhrase'] ?? '' + ); } return $response; -- GitLab