Breaking: #107324 - Streamline PSR-7 Response Header Handling
See forge#107324
Description
The handling of PSR-7 response headers in TYPO3 Core and Extbase has been unified. Previously, different mechanisms caused inconsistent behavior:
- Extbase only kept the last value of a header, discarding all
previous values (e.g. only one
Set-header was possible).Cookie - Core allowed multiple
Set-headers, but merged all other headers with multiple values into a single comma-separated string. According to RFC 9110, this is only valid for headers that explicitly support comma-separated lists.Cookie
With this change, TYPO3 now preserves multiple header values by default. Each value is emitted as a separate header line, while single values remain a single-line header.
Impact
- Multiple header values are now always emitted as multiple header lines.
- Extbase and Core responses can now properly emit multiple headers with the
same name (e.g.
Set-,Cookie WWW-,Authenticate Link,xkey). - Extensions that relied on the old merging or overwriting behavior may need to be adapted.
Affected installations
Installations are affected if they:
- Relied on headers being merged into a comma-separated string.
- Relied on only the last header value being retained in Extbase responses.
Migration
If your use case requires merged header values, you must now implement this explicitly:
use TYPO3\CMS\Core\Http\Response;
$response = new Response();
$values = ['foo', 'bar', 'baz'];
$response = $response->withHeader('X-Foo-Bar', implode(', ', $values));
If your use case requires that only the last header value is retained, you must also handle this explicitly in your code:
use TYPO3\CMS\Core\Http\Response;
$response = new Response();
$values = ['foo', 'bar', 'baz'];
$response = $response->withHeader('X-Foo-Bar', end($values));
Note: There is another edge case not affected by this change. Multiple Extbase
plugins still cannot set multiple header values with the same name (for
example, two Extbase plugins both setting a Set- header). In this
case, the latter will override the former. Installations affected by this
scenario should resolve it by adding their own middleware.