When document is cashed, mod_cache.c stores time of cash in date variable (info->date), when it happenes debug says "Added date header". Then every other request will use this cash and date variable will always be the same with the date when cash stored. All works fine yet, but that happens if cashed document was changed: mod_cache stores new last modified date of the document in the lastmod variable, and then compares if lastmod > date then lastmod=date, debug says "lastmod is in the future replacing with now"(but date its not now, its date of last cash?). The problem is how mod_cache calculates cash expire. expiry date = now + min((date - lastmod) * factor, maxexpire) If document doesnt have Expire in the headers, then expire time will be: now + 0 * factor = now, and mod_cache will never cash document anymore, before apache restart when cashed headers with old date will be deleted. I dont know is it supposed to work this way, or maybe some removal algorithms of old cashed dates doesnt work? For now i deleted "if lastmod>date then lastmod=date" piece of code and all works fine. Also i added: expiry date = now + min(((date - lastmod) * factor) + conf->defex, maxexpire) so if i set "CacheLastModifiedFactor 0" and "CacheDefaultExpire time" in httpd.conf, i can manually add expire time in seconds if i dont want to use Expires headers, so should be the way to manually enter expire time besides Expire headers.
Thanks for the diagnosis and input. I have committed a fix for this PR which will be shipped in a future release of Apache. The fix simply changes the checking code in mod_cache (around line 853) from if (lastmod != APR_DATE_BAD) to if ((lastmod != APR_DATE_BAD) && (lastmod < date)) This forces the code into the else clause when lastmod == date. You should not remove the "if lastmod>date then lastmod=date" code since this has other negative consequences in checking for freshness. Also, adding the conf->defex value into the expiry date calculation, as you did, will either result in a longer than expected expiry date, or an expiry date of maxexpire. Please let me know if the above fix (adding "&& (lastmod < date))") fails to solve the problem for you. Thanks for using Apache and helping to make it better.
Hi, i just checked your response. Look, that if you change if (lastmod != APR_DATE_BAD) to if ((lastmod != APR_DATE_BAD) && (lastmod < date)) that will work, but it will break advantage of conf->factor future, and modified documents always will be based on conf->defex variable. So what will be the difference between document that is modified every 10 sec and another that is modified every 5 hours? As i got, the problem is that mod_cache doesnt refresh "Date" value in cached headers untill apache restart, so, instead of that fix above, line 809 should be changed from if (info->date == APR_DATE_BAD) { to if ((info->date == APR_DATE_BAD) || (lastmod >= info->date)) { this will update date header in cache after document was modified, and after that all will work fine, with conf->factor etc. as like apache was restarted.
The problem still in 2.0.44. With the fix above modified documents will never use this formula: expiry date = now + min((date - lastmod) * factor, maxexpire), because the "Date" header doesnt refresh never, lastmod always will be greater than date, isnt that a bug? So, the string around line 704 (in 2.0.44 mod_cache.c) should be changed from if (info->date == APR_DATE_BAD){ /* No, or bad date */ to if ((info->date == APR_DATE_BAD) || (lastmod > date)){ /* No, or bad date */ that will make "Date" header updated with *now* if document was modified and lastmod wont be greater than date. So the formula with conf->factor will work. Also that string around line 752 that is now if ((lastmod != APR_DATE_BAD) && (lastmod < date)) { should be changed to if ((lastmod != APR_DATE_BAD) && (lastmod <= date)) { Because in some cases, then the document was modified in the same time(same second) as requested by server, it should really expired by now and not be cached for default time. With these fixes above, it will be possible to configure the server to cache the documents for some time, BUT the documents that is modified for example every 1 second, automatically will be almost not cached.
One mistake above, line 752 if ((lastmod != APR_DATE_BAD) && (lastmod < date)) { should be changed back to simple if (lastmod != APR_DATE_BAD) { not to if ((lastmod != APR_DATE_BAD) && (lastmod <= date)) { because there will be no difference, lastmod always <= date
Can you please try this with 2.0.54, and try using mod_disk_cache instead of mod_mem_cache? Thanks
No response from user. If more information appears later, please re-open the bug, for now, file it.