[BUGFIX] Pass original extbase response object to form framework finishers 48/56048/2
authorBenjamin Franzke <bfr@qbus.de>
Wed, 21 Feb 2018 00:21:50 +0000 (01:21 +0100)
committerChristian Kuhn <lolli@schwarzbu.ch>
Thu, 8 Mar 2018 09:09:12 +0000 (10:09 +0100)
The original extbase response was passed as second parameter
to ObjectManager->get() – that did effectively nothing. The second get()
parameter is not a fallback parameter (as probably supposed by the author)
but the first constructor argument (but Response has no constructor).
Now, rather use a coalesce operator to use the original response or create
an own, if required.

Also handle the StopActionException in case no extbase response
is available (e.g. when rendered through FluidTemplateContentObject).

Due to this fixes the redirect finisher can be adapted to stop echo'ing
the response content on it's own. Directly echo'ing the response content
caused wrong Content-Length headers to be generated as the core didn't
know that content has been echo'ed. (The redirect response contains both a
header based redirect and html meta redirect; due to early echo that meta
redirect is prepended to the regular html output, and is missing in the
Content-Length calculation.)
That casused certain server environments (e.g. gzip, keep-alive,
proxy) and browsers (e.g. Android, Opera desktop) to display gzip
compressed data as garbage in the browser.

Resolves: #83822
Releases: master, 8.7
Change-Id: I4cb56e7626ea786d4b5265782b5940e60e3d2ec0
Reviewed-on: https://review.typo3.org/56048
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
typo3/sysext/form/Classes/Domain/Finishers/RedirectFinisher.php
typo3/sysext/form/Classes/ViewHelpers/RenderViewHelper.php

index 178b70c..4738ece 100644 (file)
@@ -130,7 +130,6 @@ class RedirectFinisher extends AbstractFinisher
             $this->response->setStatus($statusCode);
             $this->response->setHeader('Location', (string)$uri);
         }
-        echo $this->response->shutdown();
         throw new StopActionException('redirectToUri', 1477070964);
     }
 
index 7882ba6..29cd633 100644 (file)
@@ -95,8 +95,20 @@ class RenderViewHelper extends AbstractViewHelper
 
         $factory = $renderingContext->getObjectManager()->get($factoryClass);
         $formDefinition = $factory->build($overrideConfiguration, $prototypeName);
-        $response = $renderingContext->getObjectManager()->get(Response::class, $renderingContext->getControllerContext()->getResponse());
+        $response = $renderingContext->getControllerContext()->getResponse() ?? $renderingContext->getObjectManager()->get(Response::class);
         $form = $formDefinition->bind($renderingContext->getControllerContext()->getRequest(), $response);
+
+        // If the controller context does not contain a response object, this viewhelper is used in a
+        // fluid template rendered by the FluidTemplateContentObject. Handle the StopActionException
+        // as there is no extbase dispatcher involved that catches that. */
+        if ($renderingContext->getControllerContext()->getResponse() === null) {
+            try {
+                return $form->render();
+            } catch (\TYPO3\CMS\Extbase\Mvc\Exception\StopActionException $exception) {
+                return $response->shutdown();
+            }
+        }
+
         return $form->render();
     }
 }