diff --git a/controller/Controller.class.php b/controller/Controller.class.php index 74284344..690c9134 100644 --- a/controller/Controller.class.php +++ b/controller/Controller.class.php @@ -34,6 +34,10 @@ class Controller Response::setContent($layout ? View::render('layout/basic', ['content' => $content] + $layoutParams) : $content); Response::setDefaultSecurityHeaders(); + if (Request::isGzipAccepted()) + { + Response::gzipContentIfNotDisabled(); + } Response::send(); } catch (StopException $e) diff --git a/controller/Request.class.php b/controller/Request.class.php index 73935ac5..3560e0c8 100644 --- a/controller/Request.class.php +++ b/controller/Request.class.php @@ -56,4 +56,9 @@ class Request { return isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : ''; } + + public static function isGzipAccepted(): bool + { + return isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos(strtolower($_SERVER['HTTP_ACCEPT_ENCODING']), 'gzip') !== false; + } } \ No newline at end of file diff --git a/view/Response.class.php b/view/Response.class.php index 2cee4c3e..72c71a2f 100644 --- a/view/Response.class.php +++ b/view/Response.class.php @@ -18,6 +18,7 @@ class Response const HEADER_CONTENT_LENGTH = 'Content-Length'; const HEADER_CONTENT_DISPOSITION = 'Content-Disposition'; const HEADER_CONTENT_TYPE_OPTIONS = 'X-Content-Type-Options'; + const HEADER_CONTENT_ENCODING = 'Content-Encoding'; protected static $metaDescription = '', @@ -35,6 +36,7 @@ class Response $content = '', $contentSent = false, $isHeadersOnly = false, + $gzipResponseContent = true, // $bodyCssClasses = [], $metaImages = []; @@ -115,6 +117,26 @@ class Response return static::$assets['js']; } + public static function setGzipResponseContent($gzip = true) + { + static::$gzipResponseContent = $gzip; + } + + public static function gzipContentIfNotDisabled() + { + if (static::$gzipResponseContent) + { + $content = static::getContent(); + if (strlen($content) > 256) // not worth it for really short content + { + $compressed = gzencode($content, 6); + static::setContent($compressed); + static::setHeader(static::HEADER_CONTENT_LENGTH, strlen($compressed)); + static::setHeader(static::HEADER_CONTENT_ENCODING, 'gzip'); + } + } + } + public static function send() { static::sendHeaders(); @@ -153,6 +175,7 @@ class Response public static function setDownloadHttpHeaders($name, $type = null, $size = null, $noSniff = true) { + static::setGzipResponseContent(false); // in case its already compressed static::setHeaders(array_filter([ 'Content-Disposition' => 'attachment;filename=' . $name, 'Content-Type' => $type ? 'application/zip' : null,