diff --git a/Neos.Neos/Classes/Controller/Backend/ModuleController.php b/Neos.Neos/Classes/Controller/Backend/ModuleController.php index cefecc042d7..135664fed6d 100644 --- a/Neos.Neos/Classes/Controller/Backend/ModuleController.php +++ b/Neos.Neos/Classes/Controller/Backend/ModuleController.php @@ -15,7 +15,6 @@ namespace Neos\Neos\Controller\Backend; use Neos\Flow\Annotations as Flow; -use Neos\Flow\Mvc\ActionResponse; use Neos\Flow\Mvc\Controller\ActionController; use Neos\Flow\Mvc\Dispatcher; use Neos\Flow\Security\Context; @@ -103,14 +102,18 @@ public function indexAction(array $module) $moduleResponse = $this->dispatcher->dispatch($moduleRequest); - if ($moduleResponse->getRedirectUri() !== null) { - $this->redirectToUri($moduleResponse->getRedirectUri(), 0, $moduleResponse->getStatusCode()); + if ($moduleResponse->hasHeader('Location')) { + // Preserve redirects see b57d72aeeaa2e6da4d9c0a80363025fefd63d813 + // todo just return $moduleResponse and not merge with $this->response? + $this->redirectToUri($moduleResponse->getHeaderLine('Location'), 0, $moduleResponse->getStatusCode()); } elseif ($moduleRequest->getFormat() !== 'html') { + // Allow ajax request with json or similar dd7e5c99924bf1b8618775bec08cc4f2cb1a6d2a + // todo just return $moduleResponse and not merge with $this->response? $mediaType = MediaTypes::getMediaTypeFromFilename('file.' . $moduleRequest->getFormat()); if ($mediaType !== 'application/octet-stream') { - $this->controllerContext->getResponse()->setContentType($mediaType); + $this->response->setContentType($mediaType); } - return $moduleResponse->getContent(); + return $moduleResponse->getBody(); } else { $user = $this->partyService->getAssignedPartyOfAccount($this->securityContext->getAccount()); @@ -118,7 +121,7 @@ public function indexAction(array $module) $this->view->assignMultiple([ 'moduleClass' => implode('-', $modules), - 'moduleContents' => $moduleResponse->getContent(), + 'moduleContents' => $moduleResponse->getBody()->getContents(), 'title' => $moduleRequest->hasArgument('title') ? $moduleRequest->getArgument('title') : $moduleConfiguration['label'], diff --git a/Neos.Neos/Classes/Fusion/PluginImplementation.php b/Neos.Neos/Classes/Fusion/PluginImplementation.php index eae2242db7d..dd93365d9e9 100644 --- a/Neos.Neos/Classes/Fusion/PluginImplementation.php +++ b/Neos.Neos/Classes/Fusion/PluginImplementation.php @@ -171,10 +171,17 @@ public function evaluate(): string // We need to make sure to not merge content up into the parent ActionResponse // because that would break the Fusion HttpResponse. - $content = $pluginResponse->getContent(); - $pluginResponse->setContent(''); + $content = $pluginResponse->getBody()->getContents(); - $pluginResponse->mergeIntoParentResponse($parentResponse); + // hacky, but part of the deal. We have to manipulate the global response to redirect for example. + // transfer possible headers that have been set dynamically + foreach ($pluginResponse->getHeaders() as $name => $values) { + $parentResponse->setHttpHeader($name, $values); + } + // if the status code is 200 we assume it's the default and will not overrule it + if ($pluginResponse->getStatusCode() !== 200) { + $parentResponse->setStatusCode($pluginResponse->getStatusCode()); + } return $content; } diff --git a/Neos.Neos/Classes/Service/Controller/AbstractServiceController.php b/Neos.Neos/Classes/Service/Controller/AbstractServiceController.php index 25bcb5cd135..a212f1ac725 100644 --- a/Neos.Neos/Classes/Service/Controller/AbstractServiceController.php +++ b/Neos.Neos/Classes/Service/Controller/AbstractServiceController.php @@ -14,18 +14,19 @@ namespace Neos\Neos\Service\Controller; +use GuzzleHttp\Psr7\Response; use Neos\ContentRepository\Core\SharedModel\User\UserId; use Neos\Flow\Annotations as Flow; use Neos\Flow\Exception as FlowException; use Neos\Flow\Log\ThrowableStorageInterface; use Neos\Flow\Log\Utility\LogEnvironment; use Neos\Flow\Mvc\ActionRequest; -use Neos\Flow\Mvc\ActionResponse; use Neos\Flow\Mvc\Controller\ActionController; use Neos\Flow\Mvc\Exception\ForwardException; use Neos\Flow\Mvc\Exception\StopActionException; use Neos\Neos\Controller\BackendUserTranslationTrait; use Neos\Neos\Domain\Service\UserService; +use Psr\Http\Message\ResponseInterface; /** * Abstract Service Controller @@ -85,13 +86,8 @@ protected function errorAction(): never /** * Catch exceptions while processing an exception and respond to JSON format * TODO: This is an explicit exception handling that will be replaced by format-enabled exception handlers. - * - * @param ActionRequest $request The request object - * @return ActionResponse $response The response, modified by this handler - * @throws StopActionException - * @throws \Exception */ - public function processRequest(ActionRequest $request): ActionResponse + public function processRequest(ActionRequest $request): ResponseInterface { try { $response = parent::processRequest($request); @@ -102,14 +98,16 @@ public function processRequest(ActionRequest $request): ActionResponse throw $exception; } $exceptionData = $this->convertException($exception); - $response = new ActionResponse(); - $response->setContentType('application/json'); - if ($exception instanceof FlowException) { - $response->setStatusCode($exception->getStatusCode()); - } else { - $response->setStatusCode(500); - } - $response->setContent(json_encode(['error' => $exceptionData], JSON_THROW_ON_ERROR)); + $body = json_encode(['error' => $exceptionData], JSON_THROW_ON_ERROR); + $response = new Response( + status: $exception instanceof FlowException + ? $exception->getStatusCode() + : 500, + headers: [ + 'Content-Type' => 'application/json' + ], + body: $body + ); $this->logger->error( $this->throwableStorage2->logThrowable($exception), LogEnvironment::fromMethodName(__METHOD__)