diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-23494-AddStdWrapToConfigadditionalHeaders.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-23494-AddStdWrapToConfigadditionalHeaders.rst new file mode 100644 index 0000000000000000000000000000000000000000..6cb9bf64e3dd54f7c68a03208d31834ff540dec3 --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Feature-23494-AddStdWrapToConfigadditionalHeaders.rst @@ -0,0 +1,27 @@ +.. include:: ../../Includes.txt + +========================================================= +Feature: #23494 - Add stdWrap to config.additionalHeaders +========================================================= + +See :issue:`23494` + +Description +=========== + +Add stdWrap to the elements of the additionalHeaders array. This gives full control over sending an HTTP header. + +.. code-block:: typoscript + + config.additionalHeaders { + 10.header = foo: + 10.header.dataWrap = |{page:uid} + } + + +Impact +====== + +Allow to use stdWrap on the elements `header`, `replace` and `httpResponseCode`. Empty headers will be skipped now. + +.. index:: TypoScript diff --git a/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php b/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php index 5b0ecdce6aedfb5f4ed21316086d4f9895645207..1bc53348d98f27b602ce67039399599f83693be2 100644 --- a/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php +++ b/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php @@ -3506,17 +3506,7 @@ class TypoScriptFrontendController $this->sendCacheHeaders(); } // Set headers, if any - if (is_array($this->config['config']['additionalHeaders.'])) { - ksort($this->config['config']['additionalHeaders.']); - foreach ($this->config['config']['additionalHeaders.'] as $options) { - header( - trim($options['header']), - // "replace existing headers" is turned on by default, unless turned off - ($options['replace'] !== '0'), - ((int)$options['httpResponseCode'] ?: null) - ); - } - } + $this->sendAdditionalHeaders(); // Send appropriate status code in case of temporary content if ($this->tempContent) { $this->addTempContentHttpHeaders(); @@ -4570,6 +4560,47 @@ class TypoScriptFrontendController } } + /** + * Send additional headers from config.additionalHeaders + * + * @see \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::processOutput() + */ + protected function sendAdditionalHeaders() + { + if (!isset($this->config['config']['additionalHeaders.'])) { + return; + } + ksort($this->config['config']['additionalHeaders.']); + foreach ($this->config['config']['additionalHeaders.'] as $options) { + if (!is_array($options)) { + continue; + } + $header = $options['header'] ?? ''; + $header = isset($options['header.']) + ? $this->cObj->stdWrap(trim($header), $options['header.']) + : trim($header); + if ($header === '') { + continue; + } + $replace = $options['replace'] ?? ''; + $replace = isset($options['replace.']) + ? $this->cObj->stdWrap($replace, $options['replace.']) + : $replace; + $httpResponseCode = $options['httpResponseCode'] ?? ''; + $httpResponseCode = isset($options['httpResponseCode.']) + ? $this->cObj->stdWrap($httpResponseCode, $options['httpResponseCode.']) + : $httpResponseCode; + $httpResponseCode = (int)$httpResponseCode; + + header( + $header, + // "replace existing headers" is turned on by default, unless turned off + $replace !== '0', + $httpResponseCode ?: null + ); + } + } + /** * Returns the current BE user. * diff --git a/typo3/sysext/t3editor/Resources/Private/tsref.xml b/typo3/sysext/t3editor/Resources/Private/tsref.xml index a17cf510daaab2b571ba6a72ff2083210a750028..69ecad8a54f3125a386f7362f9fdc98d79679f50 100644 --- a/typo3/sysext/t3editor/Resources/Private/tsref.xml +++ b/typo3/sysext/t3editor/Resources/Private/tsref.xml @@ -207,19 +207,33 @@ Note: If you're working on a server where you have both internal and external ac <default><![CDATA[ ]]></default> </property> - <property name="additionalHeaders" type="string"> - <description><![CDATA[strings divided by "|" - This is additional headers. You separate each header by a vertical line "|". Â Normally TYPO3 does not send any headers with the Header()-function in PHP. + <property name="additionalHeaders" type="additionalHeadersArray"> + <description><![CDATA[This property can be used to define additional HTTP headers. -Examples: -Content-Type: text/vnd.wap.wml -(this will sent a content-header for a WAP-site) +For each numeric index, there are the following sub-properties: + +header: The header string. + +replace: Optional. If set, previous headers with the same name are replaced with the current one. Default is "1". + +httpResponseCode: Optional. HTTP status code as an integer. -Content-Type: image/gif | Expires: Mon, 26 Jul 1997 05:00:00 GMT -(this will sent a content-header for a GIF-file and a Expires header) +Example: + +config.additionalHeaders { + 10 { + # The header string + header = WWW-Authenticate: Negotiate -Location: www.typo3.org -(This redirects the page to www.typo3.org)]]></description> + # Do not replace previous headers with the same name. + replace = 0 + + # Force a 401 HTTP response code + httpResponseCode = 401 + } + # Always set cache headers to private, overwriting the default TYPO3 Cache-control header + 20.header = Cache-control: Private +}]]></description> <default><![CDATA[ ]]></default> </property> @@ -6998,4 +7012,48 @@ The userfunction must return an <A>-tag.]]></description> ]]></description> </property> </type> + <type id="additionalHeadersArray" extends="array"> + <property name="10" type="additionalHeadersItem"> + <description><![CDATA[Defines a header. + +Must at least contain the header property.]]></description> + <default><![CDATA[]]></default> + </property> + <property name="20" type="additionalHeadersItem"> + <description><![CDATA[Defines a header. + +Must at least contain the header property.]]></description> + <default><![CDATA[]]></default> + </property> + <property name="30" type="additionalHeadersItem"> + <description><![CDATA[Defines a header. + +Must at least contain the header property.]]></description> + <default><![CDATA[]]></default> + </property> + <property name="40" type="additionalHeadersItem"> + <description><![CDATA[Defines a header. + +Must at least contain the header property.]]></description> + <default><![CDATA[]]></default> + </property> + </type> + <type id="additionalHeadersItem"> + <property name="header" type="stdWrap"> + <description><![CDATA[The header string]]></description> + <default><![CDATA[]]></default> + </property> + <property name="replace" type="stdWrap"> + <description><![CDATA[Optional. + +If set, previous headers with the same name are replaced with the current one. + +Default is "1".]]></description> + <default><![CDATA[1]]></default> + </property> + <property name="httpResponseCode" type="stdWrap"> + <description><![CDATA[Optional. HTTP status code as an integer.]]></description> + <default><![CDATA[]]></default> + </property> + </type> </tsRef>