diff --git a/lib/Minify.php b/lib/Minify.php index 9c56bff..e5f1a5c 100644 --- a/lib/Minify.php +++ b/lib/Minify.php @@ -93,10 +93,10 @@ class Minify { * 'contentTypeCharset' : appended to the Content-Type header sent. Set to a falsey * value to remove. (default 'UTF-8') * - * 'setExpires' : set this to a timestamp to have Minify send an HTTP Expires - * header instead of checking for conditional GET (default null). - * E.g. ($_SERVER['REQUEST_TIME'] + 86400 * 365) for 1yr - * Note this has nothing to do with server-side caching. + * 'maxAge' : set this to the number of seconds the client should use its cache + * before revalidating with the server. This sets Cache-Control: max-age and the + * Expires header. Unlike the old 'setExpires' setting, this setting will NOT + * prevent conditional GETs. Note this has nothing to do with server-side caching. * * 'debug' : set to true to minify all sources with the 'Lines' controller, which * eases the debugging of combined files. This also prevents 304 responses. @@ -148,6 +148,7 @@ class Minify { $options = $controller->analyzeSources($options); self::$_options = $controller->mixInDefaultOptions($options); + // check request validity if (! $controller->sources) { // invalid request! if (! self::$_options['quiet']) { @@ -169,44 +170,36 @@ class Minify { if (self::$_options['debug']) { self::_setupDebug($controller->sources); - self::$_options['setExpires'] = time(); + self::$_options['maxAge'] = 0; } - - if (null === self::$_options['setExpires']) { - // conditional GET - require_once 'HTTP/ConditionalGet.php'; - $cg = new HTTP_ConditionalGet(array( - 'lastModifiedTime' => self::$_options['lastModifiedTime'] - ,'isPublic' => self::$_options['isPublic'] - )); - if ($cg->cacheIsValid) { - // client's cache is valid - if (! self::$_options['quiet']) { - $cg->sendHeaders(); - return; - } else { - return array( - 'success' => true - ,'statusCode' => 304 - ,'content' => '' - ,'headers' => array() - ); - } + + // check client cache + require_once 'HTTP/ConditionalGet.php'; + $cgOptions = array( + 'lastModifiedTime' => self::$_options['lastModifiedTime'] + ,'isPublic' => self::$_options['isPublic'] + ); + if (null !== self::$_options['maxAge']) { + $cgOptions['maxAge'] = self::$_options['maxAge']; + } + $cg = new HTTP_ConditionalGet($cgOptions); + if ($cg->cacheIsValid) { + // client's cache is valid + if (! self::$_options['quiet']) { + $cg->sendHeaders(); + return; } else { - // client will need output - $headers = $cg->getHeaders(); - unset($cg); + return array( + 'success' => true + ,'statusCode' => 304 + ,'content' => '' + ,'headers' => $cg->getHeaders() + ); } } else { - // don't need conditional GET - $privacy = self::$_options['isPublic'] - ? 'public' - : 'private'; - $headers = array( - 'Cache-Control' => $privacy . ', max-age=' - . (self::$_options['setExpires'] - $_SERVER['REQUEST_TIME']) - ,'Expires' => gmdate('D, d M Y H:i:s \G\M\T', self::$_options['setExpires']) - ); + // client will need output + $headers = $cg->getHeaders(); + unset($cg); } // determine encoding @@ -226,6 +219,7 @@ class Minify { self::$_options['encodeMethod'] = ''; // identity (no encoding) } + // check server cache if (null !== self::$_cache) { // using cache // the goal is to use only the cache methods to sniff the length and diff --git a/lib/Minify/Controller/Base.php b/lib/Minify/Controller/Base.php index 7a54435..5f3390b 100644 --- a/lib/Minify/Controller/Base.php +++ b/lib/Minify/Controller/Base.php @@ -45,7 +45,7 @@ abstract class Minify_Controller_Base { ,'encodeLevel' => 9 ,'minifierOptions' => array() // no minifier options ,'contentTypeCharset' => 'UTF-8' - ,'setExpires' => null // use conditional GET + ,'maxAge' => null // no Expires/max-age ,'quiet' => false // serve() will send headers and output ,'debug' => false diff --git a/web/test/test_Minify.php b/web/test/test_Minify.php index fe8e004..6c5a12e 100644 --- a/web/test/test_Minify.php +++ b/web/test/test_Minify.php @@ -23,7 +23,12 @@ function test_Minify() 'success' => true ,'statusCode' => 304 ,'content' => '', - 'headers' => array() + 'headers' => array( + 'Last-Modified' => gmdate('D, d M Y H:i:s \G\M\T', $lastModified), + 'ETag' => "\"{$lastModified}pub\"", + 'Cache-Control' => 'max-age=0, public, must-revalidate', + '_responseCode' => 'HTTP/1.0 304 Not Modified', + ) ); $output = Minify::serve('Files', array( 'files' => $thisDir . '/_test_files/css/styles.css' // controller casts to array @@ -43,20 +48,24 @@ function test_Minify() //! class_exists('Cache_Lite_File', false) ! class_exists('HTTP_Encoder', false) && ! class_exists('Minify_CSS', false) - ,'Encoder.php, CSS.php not loaded' + && ! class_exists('Minify_Cache', false) + ,'Encoder.php, CSS.php, Cache.php not loaded' ); // Test minifying JS and serving with Expires header $content = preg_replace('/\\r\\n?/', "\n", file_get_contents($minifyTestPath . '/minified.js')); + $lastModified = filemtime($minifyTestPath . '/minified.js'); $expected = array( 'success' => true ,'statusCode' => 200 // Minify_Javascript always converts to \n line endings ,'content' => $content ,'headers' => array ( - 'Cache-Control' => 'public, max-age=86400', - 'Expires' => gmdate('D, d M Y H:i:s \G\M\T', $tomorrow), + 'Expires' => gmdate('D, d M Y H:i:s \G\M\T', $tomorrow), + 'Last-Modified' => gmdate('D, d M Y H:i:s \G\M\T', $lastModified), + 'ETag' => "\"{$lastModified}pub\"", + 'Cache-Control' => 'max-age=86400, public, must-revalidate', 'Content-Length' => strlen($content), 'Content-Type' => 'application/x-javascript; charset=UTF-8', ) @@ -67,7 +76,7 @@ function test_Minify() ,$minifyTestPath . '/QueryString.js' ) ,'quiet' => true - ,'setExpires' => $tomorrow + ,'maxAge' => 86400 ,'encodeOutput' => false )); $passed = assertTrue($expected === $output, 'Minify : JS and Expires');