diff options
| author | Christoph Brill <opensource@christophbrill.de> | 2026-08-03 00:44:38 +0200 |
|---|---|---|
| committer | Christoph Brill <opensource@christophbrill.de> | 2026-08-03 00:44:38 +0200 |
| commit | 94906c9add9427002eaa9d1e7c3bdbf50291399d (patch) | |
| tree | 538936352a297e23411ee12eca2c2badf257da24 | |
| parent | 159752fcc4c6a889d89111a529d514f3d4960f1a (diff) | |
Answer from the browser cache while the log is unchanged
| -rw-r--r-- | common.inc.php | 47 | ||||
| -rwxr-xr-x | index.php | 14 | ||||
| -rwxr-xr-x | json.php | 12 |
3 files changed, 73 insertions, 0 deletions
diff --git a/common.inc.php b/common.inc.php index 95747d9..39af7ad 100644 --- a/common.inc.php +++ b/common.inc.php @@ -86,6 +86,53 @@ function validDate($date) } /** + * Answer the request from the browser cache if the log did not change + * + * The logs of past days never change, and the log of the current day only ever + * grows, so its modification time and size identify the content. Everything + * that changes the rendering (the channel, the display options, ...) has to be + * part of $variant, otherwise a cached response would be reused for a request + * that renders something else. + * + * Sends the caching headers and, if the browser already has the current + * version, terminates the request with '304 Not Modified'. + * + * @param string $filename the log file the response is rendered from + * @param string $variant everything besides the log that affects the output + * + * @return void + */ +function cacheOnLog($filename, $variant) +{ + // A missing log may show up at any time, so do not let it be cached + if (!is_file($filename)) { + header('Cache-Control: no-cache'); + return; + } + + $mtime = filemtime($filename); + $etag = '"'.md5($mtime.'-'.filesize($filename).'-'.$variant).'"'; + + header('ETag: '.$etag); + header('Last-Modified: '.gmdate('D, d M Y H:i:s', $mtime).' GMT'); + // Today's log still grows, so always revalidate instead of serving a stale + // response from the cache without asking + header('Cache-Control: no-cache'); + + $since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) + ? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) : false; + $match = isset($_SERVER['HTTP_IF_NONE_MATCH']) + ? trim($_SERVER['HTTP_IF_NONE_MATCH']) : false; + + // The ETag is the authoritative check, only fall back to the timestamp if + // the browser did not send one + if ($match !== false ? $match === $etag : ($since !== false && $since >= $mtime)) { + header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified'); + exit; + } +} + +/** * Read a log file line by line * * Reading the whole log using file() keeps every single line in memory at once, @@ -57,6 +57,20 @@ if (isset($_GET['highlight_names'])) { ); } +// Let the browser reuse its copy as long as the log did not change. The +// variant covers everything besides the log that ends up in the HTML. +if (isset($date)) { + cacheOnLog( + LOG_DIR.'dri-devel-'.$date.'.log', + implode( + '|', array( + $channel, $date, $show_html, $show_joins, $show_irssi, + $highlight_names, + ) + ) + ); +} + $colors = array('#009900', '#CC3300', '#330099', '#FF6600', '#CC33CC', '#66CCCC', '#FF0066', '#9900FF', '#00FFCC', '#6600FF'); echo '<!DOCTYPE html> @@ -43,6 +43,18 @@ $filename = 'dri-devel-'.$date.'.log'; header("Content-type: application/json;"); +// Let the browser reuse its copy as long as the log did not change. 'maxdate' +// is part of the variant because it rolls over at midnight. +cacheOnLog( + LOG_DIR.$filename, + implode( + '|', array( + $channel, $date, validDate('today'), $_GET['mode'], + isset($_GET['users']) ? $_GET['users'] : '', + ) + ) +); + $retval = array(); $retval['maxdate'] = validDate('today'); $retval['channel'] = $channel; |
