getAssetDirectory() . '/' . basename($file); $phpOutputCompressionEnabled = ProxyHttp::isPhpOutputCompressed(); if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && !$phpOutputCompressionEnabled) { $acceptEncoding = $_SERVER['HTTP_ACCEPT_ENCODING']; if (extension_loaded('zlib') && function_exists('file_get_contents') && function_exists('file_put_contents')) { if (preg_match('/(?:^|, ?)(deflate)(?:,|$)/', $acceptEncoding, $matches)) { $encoding = 'deflate'; $filegz = $compressedFileLocation . '.deflate'; } else if (preg_match('/(?:^|, ?)((x-)?gzip)(?:,|$)/', $acceptEncoding, $matches)) { $encoding = $matches[1]; $filegz = $compressedFileLocation . '.gz'; } if (!empty($encoding)) { // compress-on-demand and use cache if (!file_exists($filegz) || ($fileModifiedTime > @filemtime($filegz))) { $data = file_get_contents($file); if ($encoding == 'deflate') { $data = gzdeflate($data, 9); } else if ($encoding == 'gzip' || $encoding == 'x-gzip') { $data = gzencode($data, 9); } file_put_contents($filegz, $data); } $compressed = true; $file = $filegz; } } else { // manually compressed $filegz = $compressedFileLocation . '.gz'; if (preg_match('/(?:^|, ?)((x-)?gzip)(?:,|$)/', $acceptEncoding, $matches) && file_exists($filegz) && ($fileModifiedTime < @filemtime($filegz))) { $encoding = $matches[1]; $compressed = true; $file = $filegz; } } } @header('Last-Modified: ' . $lastModified); if (!$phpOutputCompressionEnabled) { @header('Content-Length: ' . filesize($file)); } if (!empty($contentType)) { @header('Content-Type: ' . $contentType); } if ($compressed) { @header('Content-Encoding: ' . $encoding); } if (!_readfile($file)) { self::setHttpStatus('505 Internal server error'); } } } else { self::setHttpStatus('404 Not Found'); } } /** * Test if php output is compressed * * @return bool True if php output is (or suspected/likely) to be compressed */ public static function isPhpOutputCompressed() { // Off = ''; On = '1'; otherwise, it's a buffer size $zlibOutputCompression = ini_get('zlib.output_compression'); // could be ob_gzhandler, ob_deflatehandler, etc $outputHandler = ini_get('output_handler'); // output handlers can be stacked $obHandlers = array_filter(ob_list_handlers(), function ($var) { return $var !== "default output handler"; }); // user defined handler via wrapper if (!defined('PIWIK_TEST_MODE')) { $autoPrependFile = ini_get('auto_prepend_file'); $autoAppendFile = ini_get('auto_append_file'); } return !empty($zlibOutputCompression) || !empty($outputHandler) || !empty($obHandlers) || !empty($autoPrependFile) || !empty($autoAppendFile); } /** * Workaround IE bug when downloading certain document types over SSL and * cache control headers are present, e.g., * * Cache-Control: no-cache * Cache-Control: no-store,max-age=0,must-revalidate * Pragma: no-cache * * @see http://support.microsoft.com/kb/316431/ * @see RFC2616 * * @param string $override One of "public", "private", "no-cache", or "no-store". (optional) */ public static function overrideCacheControlHeaders($override = null) { if ($override || self::isHttps()) { @header('Pragma: '); @header('Expires: '); if (in_array($override, array('public', 'private', 'no-cache', 'no-store'))) { @header("Cache-Control: $override, must-revalidate"); } else { @header('Cache-Control: must-revalidate'); } } } /** * Set response header, e.g., HTTP/1.0 200 Ok * * @param string $status Status * @return bool */ protected static function setHttpStatus($status) { if (substr_compare(PHP_SAPI, '-fcgi', -5)) { @header($_SERVER['SERVER_PROTOCOL'] . ' ' . $status); } else { // FastCGI @header('Status: ' . $status); } } }