add gzip compression in a cache-compatible way

we can't just let nginx handle it

- http://stackoverflow.com/q/27828576/182709
- https://github.com/metacpan/metacpan-api/issues/240
This commit is contained in:
Alex Grintsvayg 2016-09-01 20:01:57 -04:00
parent 7b8ec49dd6
commit 6b3ad6cfb3
3 changed files with 32 additions and 0 deletions

View file

@ -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)

View file

@ -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;
}
}

View file

@ -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,