From b9e4b6dd49e8f2c56025df8424137144723d2021 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Sun, 13 Sep 2009 17:30:50 -0400 Subject: [PATCH] Generate ETags for pages which don't specify themselves. --- index.php | 2 +- lib/action.php | 81 +++++++++++++++++++++++++++++++++++--------------- 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/index.php b/index.php index 7669778f64..72ceb45df2 100644 --- a/index.php +++ b/index.php @@ -227,7 +227,7 @@ function main() try { if ($action_obj->prepare($args)) { - $action_obj->handle($args); + $action_obj->handleWrapper($args); } } catch (ClientException $cex) { $cac = new ClientErrorAction($cex->getMessage(), $cex->getCode()); diff --git a/lib/action.php b/lib/action.php index 670eb498c1..06cdbdfe0f 100644 --- a/lib/action.php +++ b/lib/action.php @@ -872,6 +872,63 @@ class Action extends HTMLOutputter // lawsuit return is_string($arg) ? trim($arg) : $arg; } + /** + * Wrapper for the handle method that handles etags, last-modified, and other conditional headers + * + * @param array $argarray is ignored since it's now passed in in prepare() + * + * @return boolean is read only action? + */ + function handleWrapper($argarray=null) + { + header('Vary: Accept-Encoding,Cookie,Accept-Language,Authorization'); + header("Cache-Control: must-revalidate"); + $lm = $this->lastModified(); + $etag = $this->etag(); + if ($etag) { + header('ETag: ' . $etag); + } + $if_none_match = (array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER)) ? + $_SERVER['HTTP_IF_NONE_MATCH'] : null; + if ($lm) { + header('Last-Modified: ' . date(DATE_RFC1123, $lm)); + if (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER)) { + $if_modified_since = $_SERVER['HTTP_IF_MODIFIED_SINCE']; + $ims = strtotime($if_modified_since); + if ($lm <= $ims) { + if (!$if_none_match || + !$etag || + $this->_hasEtag($etag, $if_none_match)) { + header('HTTP/1.1 304 Not Modified'); + header('Content-Length: 0'); + // Better way to do this? + exit(0); + } + } + } + } + if($etag) { + $ret = $this->handle($argarray); + }else{ + ob_start(); + $ret = $this->handle($argarray); + $output = ob_get_contents(); + ob_end_clean(); + //deep etag + $etag = md5($output); + header('ETag: ' . $etag); + if($if_none_match && $this->_hasEtag($etag, $if_none_match)) { + header('HTTP/1.1 304 Not Modified'); + header('Content-Length: 0'); + // Better way to do this? + exit(0); + } + header('Content-Length: '.strlen($output)); + print $output; + } + return $ret; + } + /** * Handler method * @@ -881,30 +938,6 @@ class Action extends HTMLOutputter // lawsuit */ function handle($argarray=null) { - header('Vary: Accept-Encoding,Cookie'); - $lm = $this->lastModified(); - $etag = $this->etag(); - if ($etag) { - header('ETag: ' . $etag); - } - if ($lm) { - header('Last-Modified: ' . date(DATE_RFC1123, $lm)); - if (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER)) { - $if_modified_since = $_SERVER['HTTP_IF_MODIFIED_SINCE']; - $ims = strtotime($if_modified_since); - if ($lm <= $ims) { - $if_none_match = (array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER)) ? - $_SERVER['HTTP_IF_NONE_MATCH'] : null; - if (!$if_none_match || - !$etag || - $this->_hasEtag($etag, $if_none_match)) { - header('HTTP/1.1 304 Not Modified'); - // Better way to do this? - exit(0); - } - } - } - } } /**