Cachify HDD expiry

Only recently I found out about the embedded Lua interpreter in Nginx and an immediate use came to my mind: why not use Lua to check validity of the Cachify harddisk (HDD) cache? Here is what I came up with.

Please note that you will need Nginx to have Lua support compiled. This is true e.g. for the nginx-extras package in Ubuntu.

Firstly, an expiry date must be written to the cached files. Easiest is to add the expiry date based on the expiry setting of Cachify to the signature at the end of any cached html file.

diff --git a/inc/cachify_hdd.class.php b/inc/cachify_hdd.class.php
index 1803df3..9fbf35c 100644
--- a/inc/cachify_hdd.class.php
+++ b/inc/cachify_hdd.class.php
@@ -49,7 +49,7 @@ final class Cachify_HDD {
 	*
 	* @param   string   $hash      Hash des Eintrags [optional]
 	* @param   string   $data      Inhalt des Eintrags
-	* @param   integer  $lifetime  Lebensdauer des Eintrags [optional]
+	* @param   integer  $lifetime  Lebensdauer des Eintrags
 	*/

 	public static function store_item($hash, $data, $lifetime)
@@ -61,7 +61,7 @@ final class Cachify_HDD {

 		/* Speichern */
 		self::_create_files(
-			$data . self::_cache_signatur()
+			$data . self::_cache_signatur($lifetime)
 		);
 	}

@@ -77,9 +77,8 @@ final class Cachify_HDD {

 	public static function get_item()
 	{
-		return is_readable(
-			self::_file_html()
-		);
+		// Always update cached file (TODO check if cache is still valid)
+		return false;
 	}

@@ -156,18 +155,25 @@ final class Cachify_HDD {
 	* @since   2.0
 	* @change  2.0.5
 	*
+	* @param   integer $lifetime  Lebensdauer des Eintrags
+	*
 	* @return  string  $diff  Signatur als String
 	*/

-	private static function _cache_signatur()
+	private static function _cache_signatur($lifetime)
 	{
 		return sprintf(
-			"\n\n<!-- %s\n%s @ %s -->",
+			"\n\n<!-- %s\n%s @ %s\n%s %s UTC-->",
 			'Cachify | http://cachify.de',
 			'HDD Cache',
 			date_i18n(
 				'd.m.Y H:i:s',
 				current_time('timestamp')
+			),
+			'valid until',
+			date_i18n(
+				'd.m.Y H:i:s',
+				time() + $lifetime
 			)
 		);
 	}
@@ -380,4 +386,4 @@ final class Cachify_HDD {
 	{
 		return self::_file_path(). 'index.html.gz';
 	}
-}
\ No newline at end of file
+}

But of course this is not where „the magic happens“ 😉
For the cache management, Nginx must be configured to look for cached files and fall back to PHP when the cache validity has expired.

location ~ /wp-content/cache/ {
	internal;
	try_files $uri $uri/ =404;
}

location @cache {
	content_by_lua '
		local cache_loc = "/wp-content/cache/cachify/" .. ngx.var.http_host .. ngx.var.uri .. "index.html"
		local res = ngx.location.capture(cache_loc)
		if res.status == ngx.HTTP_OK then
		    _, _, timestr = string.find(res.body, "valid until ([^%c]*) UTC%-%->$")
		    if timestr ~= nil then
			_, _, day, month, year, hour, minute, second = string.find(timestr, "(%d+)%.(%d+)%.(%d+) (%d+):(%d+):(%d+)")
			local timestamp = os.time({year = year, month = month, day = day, hour = hour, min = minute, sec = second})
			if timestamp > ngx.req.start_time() then
			    ngx.header.content_type = "text/html";
			    ngx.send_headers()
			    ngx.print(res.body)
			    return ngx.exit(ngx.HTTP_OK)
			end
		    end
		end
		return ngx.exec("/index.php", ngx.var.args)';
}

location @nocache {
	index index.php;
	try_files $uri $uri/ /index.php?$args;
}

location / {
	if ( $query_string ) {
		return 405;
	}
	if ( $request_method = POST ) {
		return 405;
	}
	if ( $request_uri ~ /wp-admin/ ) {
		return 405;
	}
	if ( $http_cookie ~ (wp-postpass|wordpress_logged_in|comment_author)_ ) {
		return 405;
	}

	error_page 405 = @nocache;

	index index.html /index.html;

	try_files $uri $uri/ @cache;
}

Looking forward to any feedback.