Skip to content

Commit c61941f

Browse files
committed
[BUGFIX] Ensure correct content type header can be sent
1 parent 58b0edc commit c61941f

1 file changed

Lines changed: 29 additions & 2 deletions

File tree

Classes/Middleware/TypoScriptRenderingMiddleware.php

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
class TypoScriptRenderingMiddleware implements MiddlewareInterface
2626
{
2727
private const argumentNamespace = 'tx_typoscriptrendering';
28+
private const defaultContentType = 'text/html';
2829

2930
/**
3031
* Dispatches the request to the corresponding typoscript_rendering configuration
@@ -37,21 +38,47 @@ class TypoScriptRenderingMiddleware implements MiddlewareInterface
3738
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
3839
{
3940
$frontendController = $GLOBALS['TSFE'];
41+
$requestedContentType = $frontendController->config['config']['contentType'] ?? self::defaultContentType;
4042
if (!$frontendController->isGeneratePage() || !isset($request->getQueryParams()[self::argumentNamespace])) {
41-
return $handler->handle($request);
43+
return $this->amendContentType($handler->handle($request), $requestedContentType);
4244
}
4345
$this->ensureRequiredEnvironment();
4446

4547
$frontendController->config['config']['debug'] = 0;
4648
$frontendController->config['config']['disableAllHeaderCode'] = 1;
49+
$frontendController->config['config']['disableCharsetHeader'] = 0;
4750
$frontendController->pSetup = [
4851
'10' => 'TYPOSCRIPT_RENDERING',
4952
'10.' => [
5053
'request' => $request->getQueryParams()[self::argumentNamespace],
5154
],
5255
];
5356

54-
return $handler->handle($request);
57+
return $this->amendContentType($handler->handle($request), $requestedContentType);
58+
}
59+
60+
/**
61+
* TYPO3's frontend rendering allows to influence the content type,
62+
* but does not store this information in cache, which leads to wrong content type
63+
* to be sent when content if pulled from cache.
64+
* We add a tiny workaround, that allows plugins to set the content type, but also
65+
* store the content type in cache:
66+
*
67+
* $GLOBALS['TSFE']->setContentType('application/json');
68+
* $GLOBALS['TSFE']->config['config']['contentType'] = 'application/json';
69+
*
70+
* @param ResponseInterface $response
71+
* @param string $requestedContentType
72+
* @return ResponseInterface
73+
*/
74+
private function amendContentType(ResponseInterface $response, string $requestedContentType): ResponseInterface
75+
{
76+
$originalContentTypeHeader = $response->getHeader('Content-Type')[0];
77+
if (strpos($originalContentTypeHeader, self::defaultContentType) === 0 && strpos($originalContentTypeHeader, $requestedContentType) === false) {
78+
$response = $response->withHeader('Content-Type', \str_replace(self::defaultContentType, $requestedContentType, $originalContentTypeHeader));
79+
}
80+
81+
return $response;
5582
}
5683

5784
/**

0 commit comments

Comments
 (0)