diff --git a/serendipity.css.php b/serendipity.css.php index 4ba23c13..ece63b31 100644 --- a/serendipity.css.php +++ b/serendipity.css.php @@ -66,6 +66,10 @@ if (IS_installed === false) { die(); } +// Use output buffering to capture all output. This is necessary +// because a plugin might call 'echo' directly instead of adding +// the desired output to the hook parameter '$out'. +ob_start(); // First all of our fallback classes, so they can be overridden by the usual template. $out = serendipity_printStylesheet( @@ -82,4 +86,35 @@ serendipity_plugin_api::hook_event($css_hook, $out); echo $out; +// +// Fetch output buffer containing the CSS output and create eTag header +// +$ob_buffer = ob_get_contents(); + +if ($ob_buffer) { + + // Calculate hash for eTag and get request header. The hash value + // changes with every modification to any part of the CSS styles. + // This includes the installation of a plugin that adds plugin + // specific styles. + + // Send ETag header using the hash value of the CSS code + $hashValue = md5($ob_buffer); + @header('ETag: "' . $hashValue . '"'); + + // Compare value of If-None-Match header (if available) to hash value + if (!empty($_SERVER['HTTP_IF_NONE_MATCH'])) { + // Get request header value and chop off optional quotes + $reqHeader = trim($_SERVER['HTTP_IF_NONE_MATCH'], '"'); + + if ($hashValue === $reqHeader) { + // Tell client to use the cached version and destroy output buffer + @header('HTTP/1.1 304 Not Modified', true, 304); + ob_clean(); + } + } +} + +ob_end_flush(); + /* vim: set sts=4 ts=4 expandtab : */