[BUGFIX] PSR-7: Only send headers if no other headers are prepared 22/42122/6
authorMarkus Klein <markus.klein@typo3.org>
Wed, 29 Jul 2015 22:34:12 +0000 (00:34 +0200)
committerFrank Nägler <frank.naegler@typo3.org>
Fri, 31 Jul 2015 08:10:59 +0000 (10:10 +0200)
The PSR-7 functionality to send the headers is now only in use
if the headers haven't been sent already or no other function
has declared any other headers before (e.g. Extbase).

This is an intermediate solution until Extbase and TSFE are fully
using the PSR-7 functionality.

Releases: master
Resolves: #68506
Change-Id: I9ede18119678456d7679870a2b83a684ff39344e
Reviewed-on: http://review.typo3.org/42122
Reviewed-by: Helmut Hummel <helmut.hummel@typo3.org>
Tested-by: Helmut Hummel <helmut.hummel@typo3.org>
Reviewed-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
Reviewed-by: Frank Nägler <frank.naegler@typo3.org>
Tested-by: Frank Nägler <frank.naegler@typo3.org>
typo3/sysext/core/Classes/Core/Bootstrap.php

index 606818f..686dbe2 100644 (file)
@@ -297,11 +297,21 @@ class Bootstrap {
        protected function sendResponse() {
                if ($this->response instanceof \Psr\Http\Message\ResponseInterface) {
                        if (!headers_sent()) {
+                               // headers already set by legacy code
+                               $headers = array_flip(array_map(function($value) { return strtolower(explode(':', $value, 2)[0]); }, headers_list()));
                                foreach ($this->response->getHeaders() as $name => $values) {
-                                       header($name . ': ' . implode(', ', $values), FALSE);
+                                       // if the header has already been set, do not overwrite it
+                                       if (!isset($headers[strtolower($name)])) {
+                                               header($name . ': ' . implode(', ', $values), FALSE);
+                                       }
+                               }
+                               // Send the response type only if it's different from 200.
+                               // This is a safety net if a non 200 status code has already been sent.
+                               // In case we have some non 200 code via the response object though, we write the header in any case.
+                               $statusCode = $this->response->getStatusCode();
+                               if ($statusCode !== 200) {
+                                       header('HTTP/' . $this->response->getProtocolVersion() . ' ' . $statusCode . ' ' . $this->response->getReasonPhrase());
                                }
-                               // send the response type
-                               header('HTTP/' . $this->response->getProtocolVersion() . ' ' . $this->response->getStatusCode() . ' ' . $this->response->getReasonPhrase());
                        }
                        echo $this->response->getBody()->__toString();
                }