Help to diagnose issue with Statcache Extra

Can anyone help me diagnose why Statcache fails to overwrite existing static files when a Resource is saved?

I think this really relates to Apache ignoring an Environment Variable set in .htaccess, you’ll see that’s what I start to conclude if you make it to the end of the post.

Environment

  • MODX Revolution 2.8.3-pl
  • Ubuntu Server 22.04 / NGINX / Apache/2.4.57 (Unix)
  • PHP 7.4
  • Statcache 1.4.0-pl

This is a clean install with only the Statcache Extra installed. There are 3 resources

  • home
  • parent (container)
    • child (resource)

System settings applied are

  • cache_expires = 0
  • friendly_urls = Yes
  • log_level = 3 (INFO)

Following the Wiki guide I selected all 5 Plugin Events to trigger Statcache.

The Plugin Properties are configured as

  • cacheTV empty
  • contentTypes empty
  • contexts empty
  • mimeTypes empty
  • regenerate No
  • regenerate_on_save Yes
  • regenerate_useragent MODXRegenCache (space removed from default value MODX RegenCache)
  • skipBinaryContentTypes Yes
  • skipIfTagsRemain Yes
  • skipTV empty
  • use_http_host No
  • use_url_scheme No

The /statcache directory was created manually and can see directories and files being created there.

Apache should perform rewrites for requests where a static file exists - see rules at the end (also with space removed from default value MODX RegenCache).

The MODX Error Log shows the following details when a Resource is saved

[2023-07-10 16:59:48] (INFO @ /home/webapps/domain.uk/httpdocs/core/cache/includes/elements/modplugin/14.include.cache.php : 160) Requesting Resource at https://www.domain.uk/tests/statcache.html
[2023-07-10 16:59:48] (INFO @ /home/webapps/domain.uk/httpdocs/core/cache/includes/elements/modplugin/14.include.cache.php : 163) Updated cache for resource at https://www.domain.uk/tests/statcache.html

These lines are triggered by the OnDocFormSave Event.

The server logs show the CURL request from Statcache that should regenerate static files on save

172.70.86.136 - - [10/Jul/2023:15:59:48 +0000] "HEAD /tests/statcache.html HTTP/1.0" 200 - "-" "MODXRegenCache"

Things I have checked

  • all the resources are set to Template = (empty) to eliminate the chance of a stray unncached MODX tag which would prevent Statcache saving a static file eg. the Default Template contains [[!++site_url]]
  • the .htaccess rewrite rule works - tested by manually editing the content of the static files and refrshing the relevant page in the browser
  • server logs show the CURL request from Statcache that should regenerate static files on save
172.71.178.17 - - [10/Jul/2023:14:52:07 +0000] "HEAD /tests/statcache.html HTTP/1.0" 200 - "-" "MODXRegenCache"

Since the CURL request goes out with the useragent as MODXRegenCache Apache will not rewrite the request to the static file so it hits MODX which generates the updated Resource Output. From there the OnBeforeSaveWebPageCache Event in the Statcache Plugin should save the Output to a static file starting at line #140

                /* attempt to write the complete Resource output to the static file */
                if (!$modx->cacheManager->writeFile($statcacheFile, $modx->resource->_output)) {
                    $modx->log(modX::LOG_LEVEL_ERROR, "Error caching output from Resource {$modx->resource->get('id')} to static file {$statcacheFile}", '', __FUNCTION__, __FILE__, __LINE__);
                }

The Error message for if writeFile fails does not appear in the logs so Statcache thinks it has saved the new file correctly. However neither the timestamp on the static file or its content change.

Can anyone suggest why Statcache doesen’t regenerate_on_save?

opengeek describes how it should work in version 1.4.0.

I disabled CURLOPT_NOBODY in the CURL request to and added a line to log the result of curl_exec to see what the server returns to CURL - it’s the original content, not the updated version.

[2023-07-10 17:26:06] (INFO) CURL RETURNS initial text

So it looks like Apache ignores the CACHE_PREFIX environment variable set in .htaccess.

# STATCACHE start

# if USER_AGENT is MODXRegenCache set the CACHE_PREFIX to nocache
RewriteCond %{USER_AGENT} "MODXRegenCache"
# removed space from CACHE_PREFIX as it causes 500 error
RewriteRule .* - [E=CACHE_PREFIX:nocache]

# if USER_AGENT is not MODXRegenCache set the CACHE_PREFIX to statcache
RewriteCond %{USER_AGENT} !"MODXRegenCache"
RewriteRule .* - [E=CACHE_PREFIX:statcache]

# If MODX is directly in your DOCUMENT_ROOT,
# add this before your MODX Friendly URLs RewriteCond's and RewriteRule...

# for dirctories, check if static ~index.html file exists
RewriteCond %{DOCUMENT_ROOT}/%{ENV:CACHE_PREFIX}%{REQUEST_URI}~index.html -f
RewriteRule ^(.*)$ /%{ENV:CACHE_PREFIX}/$1~index.html [L,QSA]

# for files, check if static file exists
RewriteCond %{DOCUMENT_ROOT}/%{ENV:CACHE_PREFIX}%{REQUEST_URI} -f
RewriteRule ^(.*)$ /%{ENV:CACHE_PREFIX}/$1 [L,QSA]
# STATCACHE end

I tried updating %{USER_AGENT} to %{HTTPO_USER_AGENT} as I believe USER_AGENT is depreciated but still works. The change made no difference.

Any ideas please?

Related information and resources

  • the website is behind the Cloudflare proxy, Cloudflare doesn’t cache .html files by default but I disabled it anyway - the result is the same

Statcache
https://extras.modx.com/package/statcache?version=1.4.0-pl

Github repository

I did a test and on my installation it only works, when I use %{HTTP_USER_AGENT} instead of %{USER_AGENT} and no quotes (") around MODXRegenCache:

RewriteCond %{HTTP_USER_AGENT} MODXRegenCache
RewriteRule .* - [E=CACHE_PREFIX:nocache]

RewriteCond %{HTTP_USER_AGENT} !MODXRegenCache
RewriteRule .* - [E=CACHE_PREFIX:statcache]

Legend, that resolves it for me as well, thank you.

Interesting that in the Statcache Wiki (one of) and the Apache docs (both of) the elements in the RewriteCond line are in double quotes eg.

RewriteCond %{USER_AGENT} "MODX RegenCache"

and

RewriteCond  "%{HTTP_USER_AGENT}"  "(iPhone|Blackberry|Android)"  

ref. mod_rewrite - Apache HTTP Server Version 2.4

Now I’ll need to see if I can figure the NGINX config. I ran a loader.io test on statcache through apache and the result wasn’t as quick as I expected.

Thanks again