keycdn / cache-enabler

A lightweight caching plugin for WordPress that makes your website faster by generating static HTML files.
https://wordpress.org/plugins/cache-enabler/
123 stars 46 forks source link

Function end_buffering returns incorrect value #230

Closed byteperfect closed 3 years ago

byteperfect commented 3 years ago

Inside Cache_Enabler_Engine::end_buffering function you have call of Cache_Enabler_Disk::cache_page function which in turn calls Cache_Enabler_Disk::create_cache_file function. Cache_Enabler_Disk::create_cache_file function modifies $page_contents in several places, but does not path this modified value back to Cache_Enabler_Engine::end_buffering function so we have incorrect html on first time page load. This issue could be solved easily by passing page content to Cache_Enabler_Disk::cache_page and Cache_Enabler_Disk::create_cache_file by reference:

public static function cache_page( &$page_contents )
private static function create_cache_file( &$page_contents )

Also in Cache_Enabler_Disk::create_cache_file we should handle compressing page contents:

// compress page contents with Gzip if applicable
if ( strpos( $new_cache_file_name, 'gz' ) !== false ) {
    $gziped_page_contents = gzencode( $page_contents, 9 );

    // check if Gzip compression failed
    if ( $gziped_page_contents === false ) {
        return;
    }
}

// create directory if necessary
if ( ! self::mkdir_p( $new_cache_file_dir ) ) {
    return;
}

// create new cache file
file_put_contents( $new_cache_file, isset( $gziped_page_contents ) ? $gziped_page_contents : $page_contents, LOCK_EX );
coreykn commented 3 years ago

That is intentional because Cache Enabler currently only delivers the potentially modified page contents if a cached page is being delivered, not when it's a cache miss. This only occurs if the page contents are pulled from the stored HTML and then written to the output buffer when the advanced-cache.php drop-in is included, which means only sending the page contents Cache Enabler touches to the HTML file is required.

byteperfect commented 3 years ago

Sorry, but, why not immediately send the prepared html to the browser? Actually, on this stage, the cache file for the page is already created and is waiting for the next time page load / reload.

coreykn commented 3 years ago

Like most caching systems we consider an object delivered with a cache miss to be from the original source that it was received from. For Cache Enabler that means delivering what was received during the output buffering unmodified. Only when it's a cache hit will we deliver what Cache Enabler has modified.