From 676ce0472dfedf22c60231670c51225746106bde Mon Sep 17 00:00:00 2001
From: Benni Mack <benni@typo3.org>
Date: Thu, 15 Feb 2018 21:25:53 +0100
Subject: [PATCH] [TASK] Move FE OutputCompression to PSR-15

Output Compression should be separated from the request handling, and is
now moved into a PSR-15 middleware.

This change also decouples Output Compression from Bootstrap, and the
Request Handler, so it can be re-used in other areas.

Intentionally omitted is a proper cleanup (ob_get_clean) and an explicit
write to the response object (in the middleware). That's up for later
patches. The idea of this patch is to keep functionality identical for
now.

Resolves: #83931
Releases: master
Change-Id: Ic84707cac6c858698f290069f6aa492724ce0602
Reviewed-on: https://review.typo3.org/55746
Reviewed-by: Benjamin Franzke <bfr@qbus.de>
Tested-by: Benjamin Franzke <bfr@qbus.de>
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Mathias Schreiber <mathias.schreiber@typo3.com>
Tested-by: Mathias Schreiber <mathias.schreiber@typo3.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
---
 .../frontend/Classes/Http/RequestHandler.php  | 21 -------
 .../Classes/Middleware/OutputCompression.php  | 61 +++++++++++++++++++
 .../Configuration/RequestMiddlewares.php      |  6 ++
 3 files changed, 67 insertions(+), 21 deletions(-)
 create mode 100644 typo3/sysext/frontend/Classes/Middleware/OutputCompression.php

diff --git a/typo3/sysext/frontend/Classes/Http/RequestHandler.php b/typo3/sysext/frontend/Classes/Http/RequestHandler.php
index 72934972ffbc..dd76da594cf4 100644
--- a/typo3/sysext/frontend/Classes/Http/RequestHandler.php
+++ b/typo3/sysext/frontend/Classes/Http/RequestHandler.php
@@ -26,10 +26,8 @@ use TYPO3\CMS\Core\Http\RequestHandlerInterface;
 use TYPO3\CMS\Core\Http\Response;
 use TYPO3\CMS\Core\TimeTracker\TimeTracker;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Core\Utility\MathUtility;
 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
 use TYPO3\CMS\Frontend\Page\PageGenerator;
-use TYPO3\CMS\Frontend\Utility\CompressionUtility;
 use TYPO3\CMS\Frontend\View\AdminPanelView;
 
 /**
@@ -89,11 +87,6 @@ class RequestHandler implements RequestHandlerInterface, PsrRequestHandlerInterf
         /** @var TypoScriptFrontendController $controller */
         $controller = $GLOBALS['TSFE'];
 
-        // Output compression
-        // Remove any output produced until now
-        $this->bootstrap->endOutputBufferingAndCleanPreviousOutput();
-        $this->initializeOutputCompression();
-
         // Initializing the Frontend User
         $this->timeTracker->push('Front End user initialized', '');
         $controller->initFEuser();
@@ -265,18 +258,4 @@ class RequestHandler implements RequestHandlerInterface, PsrRequestHandlerInterf
     {
         return 50;
     }
-
-    /**
-     * Initializes output compression when enabled, could be split up and put into Bootstrap
-     * at a later point
-     */
-    protected function initializeOutputCompression()
-    {
-        if ($GLOBALS['TYPO3_CONF_VARS']['FE']['compressionLevel'] && extension_loaded('zlib')) {
-            if (MathUtility::canBeInterpretedAsInteger($GLOBALS['TYPO3_CONF_VARS']['FE']['compressionLevel'])) {
-                @ini_set('zlib.output_compression_level', (string)$GLOBALS['TYPO3_CONF_VARS']['FE']['compressionLevel']);
-            }
-            ob_start([GeneralUtility::makeInstance(CompressionUtility::class), 'compressionOutputHandler']);
-        }
-    }
 }
diff --git a/typo3/sysext/frontend/Classes/Middleware/OutputCompression.php b/typo3/sysext/frontend/Classes/Middleware/OutputCompression.php
new file mode 100644
index 000000000000..4f978a0f4da3
--- /dev/null
+++ b/typo3/sysext/frontend/Classes/Middleware/OutputCompression.php
@@ -0,0 +1,61 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Frontend\Middleware;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\MathUtility;
+use TYPO3\CMS\Frontend\Utility\CompressionUtility;
+
+/**
+ * Sets up output compression
+ *
+ * @internal
+ */
+class OutputCompression implements MiddlewareInterface
+{
+    /**
+     * Clears all output and checks if a compression level is set
+     *
+     * @param ServerRequestInterface $request
+     * @param RequestHandlerInterface $handler
+     * @return ResponseInterface
+     */
+    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
+    {
+        // Throw away all output that may have happened during bootstrapping by weird extensions
+        ob_clean();
+        // Initialize output compression if configured
+        $this->initializeOutputCompression();
+        return $handler->handle($request);
+    }
+
+    /**
+     * Initialize output compression if configured
+     */
+    protected function initializeOutputCompression()
+    {
+        if ($GLOBALS['TYPO3_CONF_VARS']['FE']['compressionLevel'] && extension_loaded('zlib')) {
+            if (MathUtility::canBeInterpretedAsInteger($GLOBALS['TYPO3_CONF_VARS']['FE']['compressionLevel'])) {
+                @ini_set('zlib.output_compression_level', (string)$GLOBALS['TYPO3_CONF_VARS']['FE']['compressionLevel']);
+            }
+            ob_start([GeneralUtility::makeInstance(CompressionUtility::class), 'compressionOutputHandler']);
+        }
+    }
+}
diff --git a/typo3/sysext/frontend/Configuration/RequestMiddlewares.php b/typo3/sysext/frontend/Configuration/RequestMiddlewares.php
index 651d78a06cf8..69c26f59f6ff 100644
--- a/typo3/sysext/frontend/Configuration/RequestMiddlewares.php
+++ b/typo3/sysext/frontend/Configuration/RequestMiddlewares.php
@@ -57,5 +57,11 @@ return [
                 'typo3/cms-core/normalized-params-attribute',
             ]
         ],
+        'typo3/cms-frontend/output-compression' => [
+            'target' => \TYPO3\CMS\Frontend\Middleware\OutputCompression::class,
+            'after' => [
+                'typo3/cms-frontend/tsfe',
+            ]
+        ],
     ]
 ];
-- 
GitLab