From cce7d774d926027ed32148f3709a4cac211a2612 Mon Sep 17 00:00:00 2001
From: Benjamin Franzke <bfr@qbus.de>
Date: Tue, 20 Dec 2016 07:26:42 +0100
Subject: [PATCH] [BUGFIX] Fix non-302 redirects for PSR-7 response objects

All redirect status codes (e.g. 201,301,303,307) are incorrectly
sent as 302.

We need to set the response code before setting the Location header,
as a call to header('Location: ...'); sets the response code
implicitly to 302 (unless it has already been set to 201 or 3xx) [1].
By settings the status code/header first, header('Location: ..') will
not change the status code, if the PSR-7 response object contains a
proper redirect status code.

[1] http://php.net/manual/en/function.header.php
    The second special case is the "Location:" header.
    Not only does it send this header back to the browser, but it also
    returns a REDIRECT (302) status code to the browser unless the 201
    or a 3xx status code has already been set.

Change-Id: Ifa076e6393c6ed42d93959fe8c3a5b79cee145a4
Fixes: #79043
Releases: master, 7.6
Reviewed-on: https://review.typo3.org/51002
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Andreas Fernandez <typo3@scripting-base.de>
Reviewed-by: Philipp Gampe <philipp.gampe@typo3.org>
Tested-by: Josef Glatz <josef.glatz@typo3.org>
Reviewed-by: Marco Huber <mail@marco-huber.de>
Tested-by: Marco Huber <mail@marco-huber.de>
Reviewed-by: Joerg Boesche <typo3@joergboesche.de>
Reviewed-by: Susanne Moog <susanne.moog@typo3.org>
Tested-by: Susanne Moog <susanne.moog@typo3.org>
---
 typo3/sysext/core/Classes/Core/Bootstrap.php | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/typo3/sysext/core/Classes/Core/Bootstrap.php b/typo3/sysext/core/Classes/Core/Bootstrap.php
index 5228aacde6f3..c4a75de008c4 100644
--- a/typo3/sysext/core/Classes/Core/Bootstrap.php
+++ b/typo3/sysext/core/Classes/Core/Bootstrap.php
@@ -320,9 +320,6 @@ class Bootstrap
     {
         if ($this->response instanceof \Psr\Http\Message\ResponseInterface) {
             if (!headers_sent()) {
-                foreach ($this->response->getHeaders() as $name => $values) {
-                    header($name . ': ' . implode(', ', $values));
-                }
                 // If the response code was not changed by legacy code (still is 200)
                 // then allow the PSR-7 response object to explicitly set it.
                 // Otherwise let legacy code take precedence.
@@ -330,6 +327,10 @@ class Bootstrap
                 if (http_response_code() === 200) {
                     header('HTTP/' . $this->response->getProtocolVersion() . ' ' . $this->response->getStatusCode() . ' ' . $this->response->getReasonPhrase());
                 }
+
+                foreach ($this->response->getHeaders() as $name => $values) {
+                    header($name . ': ' . implode(', ', $values));
+                }
             }
             echo $this->response->getBody()->__toString();
         }
-- 
GitLab