From 98bda4fdc7bccbef714bd6480528804bcd3f5586 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 22 Jan 2009 22:50:10 +0100 Subject: fixed multiple gzip/sendfile problems in css and js dispatchers FS#1571 - Avoid double compression when gzip_output is enabled - Only compress when gzip_output is enabled - Do not use x-sendfile for compressed content (content-encoding is not supported) - Make sure the script terminates after using x-sendfile - Moved gzip browser support check to init.php darcs-hash:20090122215010-7ad00-765765d353ff78df5b8704086328c5c699bbe7e0.gz --- inc/init.php | 6 +++--- inc/pageutils.php | 31 +++++++++++++++++-------------- lib/exe/css.php | 15 ++++----------- lib/exe/js.php | 19 ++++++------------- 4 files changed, 30 insertions(+), 41 deletions(-) diff --git a/inc/init.php b/inc/init.php index 1d651812f..f577188e8 100644 --- a/inc/init.php +++ b/inc/init.php @@ -168,11 +168,11 @@ // increase PCRE backtrack limit @ini_set('pcre.backtrack_limit', '20971520'); - // enable gzip compression + // enable gzip compression if supported + $conf['gzip_output'] &= (strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip') !== false); if ($conf['gzip_output'] && !defined('DOKU_DISABLE_GZIP_OUTPUT') && - function_exists('ob_gzhandler') && - preg_match('/gzip|deflate/', $_SERVER['HTTP_ACCEPT_ENCODING'])) { + function_exists('ob_gzhandler')) { ob_start('ob_gzhandler'); } diff --git a/inc/pageutils.php b/inc/pageutils.php index 5fea66942..4a62244dc 100644 --- a/inc/pageutils.php +++ b/inc/pageutils.php @@ -534,7 +534,7 @@ function isVisiblePage($id){ * @author Simon Willison * @link http://simon.incutio.com/archive/2003/04/23/conditionalGet * @param timestamp $timestamp lastmodified time of the cache file - * @returns void or void with previously header() commands executed + * @returns void or exits with previously header() commands executed */ function http_conditionalRequest($timestamp){ // A PHP implementation of conditional get, see @@ -579,7 +579,10 @@ function http_conditionalRequest($timestamp){ } /** - * common routines for handling communication with the client (browser) + * Let the webserver send the given file vi x-sendfile method + * + * @author Chris Smith + * @returns void or exits with previously header() commands executed */ function http_sendfile($file) { global $conf; @@ -587,28 +590,28 @@ function http_sendfile($file) { //use x-sendfile header to pass the delivery to compatible webservers if($conf['xsendfile'] == 1){ header("X-LIGHTTPD-send-file: $file"); - return true; + ob_end_clean(); + exit; }elseif($conf['xsendfile'] == 2){ header("X-Sendfile: $file"); - return true; + ob_end_clean(); + exit; }elseif($conf['xsendfile'] == 3){ header("X-Accel-Redirect: $file"); - return true; + ob_end_clean(); + exit; } return false; } -function http_accepts_gzip() { - return !empty($_SERVER['HTTP_ACCEPT_ENCODING']) && (strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip') !== false); -} - -function http_accepts_deflate() { - return !empty($_SERVER['HTTP_ACCEPT_ENCODING']) && (strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'deflate') !== false); -} /** - * return true if there exists a gzip version of the uncompressed file (samepath/samefilename.sameext.gz) - * created after the uncompressed file + * Check for a gzipped version and create if necessary + * + * return true if there exists a gzip version of the uncompressed file + * (samepath/samefilename.sameext.gz) created after the uncompressed file + * + * @author Chris Smith */ function http_gzip_valid($uncompressed_file) { $gzip = $uncompressed_file.'.gz'; diff --git a/lib/exe/css.php b/lib/exe/css.php index 9fb247496..7fa56f4cc 100644 --- a/lib/exe/css.php +++ b/lib/exe/css.php @@ -8,6 +8,7 @@ if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../'); if(!defined('NOSESSION')) define('NOSESSION',true); // we do not use a session or authentication here (better caching) +if(!defined('DOKU_DISABLE_GZIP_OUTPUT')) define('DOKU_DISABLE_GZIP_OUTPUT',1); // we gzip ourself here require_once(DOKU_INC.'inc/init.php'); require_once(DOKU_INC.'inc/pageutils.php'); require_once(DOKU_INC.'inc/io.php'); @@ -94,14 +95,10 @@ function css_out(){ if($conf['allowdebug']) header("X-CacheUsed: $cache"); // finally send output - if (http_accepts_gzip() && http_gzip_valid($cache)) { + if ($conf['gzip_output'] && http_gzip_valid($cache)) { header('Vary: Accept-Encoding'); header('Content-Encoding: gzip'); - if (!http_sendfile($cache.'.gz')) readfile($cache.".gz"); -# } else if (http_accepts_deflate()) { -# header('Vary: Accept-Encoding'); -# header('Content-Encoding: deflate'); -# readfile($cache.".zip"); + readfile($cache.".gz"); } else { if (!http_sendfile($cache)) readfile($cache); } @@ -140,14 +137,10 @@ function css_out(){ copy($cache,"compress.zlib://$cache.gz"); // finally send output - if (http_accepts_gzip()) { + if ($conf['gzip_output']) { header('Vary: Accept-Encoding'); header('Content-Encoding: gzip'); print gzencode($css,9,FORCE_GZIP); -# } else if (http_accepts_deflate()) { -# header('Vary: Accept-Encoding'); -# header('Content-Encoding: deflate'); -# print gzencode($css,9,FORCE_DEFLATE); } else { print $css; } diff --git a/lib/exe/js.php b/lib/exe/js.php index f3acc7491..7746edcd9 100644 --- a/lib/exe/js.php +++ b/lib/exe/js.php @@ -9,6 +9,7 @@ if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../'); if(!defined('NOSESSION')) define('NOSESSION',true); // we do not use a session or authentication here (better caching) if(!defined('NL')) define('NL',"\n"); +if(!defined('DOKU_DISABLE_GZIP_OUTPUT')) define('DOKU_DISABLE_GZIP_OUTPUT',1); // we gzip ourself here require_once(DOKU_INC.'inc/init.php'); require_once(DOKU_INC.'inc/pageutils.php'); require_once(DOKU_INC.'inc/io.php'); @@ -66,14 +67,10 @@ function js_out(){ if($conf['allowdebug']) header("X-CacheUsed: $cache"); // finally send output - if (http_accepts_gzip() && http_gzip_valid($cache)) { + if ($conf['gzip_output'] && http_gzip_valid($cache)) { header('Vary: Accept-Encoding'); header('Content-Encoding: gzip'); - if (!http_sendfile($cache.'.gz')) readfile($cache.".gz"); -# } else if (http_accepts_deflate()) { -# header('Vary: Accept-Encoding'); -# header('Content-Encoding: deflate'); -# readfile($cache.".zip"); + readfile($cache.".gz"); } else { if (!http_sendfile($cache)) readfile($cache); } @@ -97,7 +94,7 @@ function js_out(){ // load JS strings form plugins $lang['js']['plugins'] = js_pluginstrings(); - + // load JS specific translations $json = new JSON(); echo 'LANG = '.$json->encode($lang['js']).";\n"; @@ -163,14 +160,10 @@ function js_out(){ copy($cache,"compress.zlib://$cache.gz"); // finally send output - if (http_accepts_gzip()) { + if ($conf['gzip_output']) { header('Vary: Accept-Encoding'); header('Content-Encoding: gzip'); print gzencode($js,9,FORCE_GZIP); -# } else if (http_accepts_deflate()) { -# header('Vary: Accept-Encoding'); -# header('Content-Encoding: deflate'); -# print gzencode($js,9,FORCE_DEFLATE); } else { print $js; } @@ -250,7 +243,7 @@ function js_pluginscripts(){ /** * Return an two-dimensional array with strings from the language file of each plugin. * - * - $lang['js'] must be an array. + * - $lang['js'] must be an array. * - Nothing is returned for plugins without an entry for $lang['js'] * * @author Gabriel Birke -- cgit v1.2.3