From fe374d90ca383832500aa087871c786b48b623ec Mon Sep 17 00:00:00 2001 From: Stathis Oureilidis Date: Mon, 16 Dec 2019 19:50:45 +0200 Subject: [PATCH 1/3] Add static brotli compression support. To be used in conjunction with https://github.com/kjdev/php-ext-brotli --- wp-cache-phase1.php | 6 +++ wp-cache-phase2.php | 111 +++++++++++++++++++++++++++++++++++++++++--- wp-cache.php | 43 +++++++++++++---- 3 files changed, 143 insertions(+), 17 deletions(-) diff --git a/wp-cache-phase1.php b/wp-cache-phase1.php index d638f351a..302f9a8ac 100644 --- a/wp-cache-phase1.php +++ b/wp-cache-phase1.php @@ -96,13 +96,19 @@ $cache_filename = ''; $meta_file = ''; $wp_cache_gzip_encoding = ''; +$wp_cache_br_encoding = ''; $gzipped = 0; $gzsize = 0; +$brotlied = 0; +$brsize = 0; if ( $cache_compression ) { $wp_cache_gzip_encoding = gzip_accepted(); } +if ( $cache_compression_br ) { + $wp_cache_br_encoding = br_accepted(); +} add_cacheaction( 'supercache_filename_str', 'wp_cache_check_mobile' ); if ( function_exists( 'add_filter' ) ) { // loaded since WordPress 4.6 diff --git a/wp-cache-phase2.php b/wp-cache-phase2.php index bc9c91c65..7ca53adb2 100644 --- a/wp-cache-phase2.php +++ b/wp-cache-phase2.php @@ -8,6 +8,14 @@ function gzip_accepted(){ return 'gzip'; } +function br_accepted(){ + if ( 1 == ini_get( 'zlib.output_compression' ) || "on" == strtolower( ini_get( 'zlib.output_compression' ) ) ) // don't compress WP-Cache data files when PHP is already doing it + return false; + + if ( !isset( $_SERVER[ 'HTTP_ACCEPT_ENCODING' ] ) || ( isset( $_SERVER[ 'HTTP_ACCEPT_ENCODING' ] ) && strpos( $_SERVER[ 'HTTP_ACCEPT_ENCODING' ], 'br' ) === false ) ) return false; + return 'br'; +} + function setup_blog_cache_dir() { global $blog_cache_dir, $cache_path; if( false == @is_dir( $blog_cache_dir ) ) { @@ -20,7 +28,7 @@ function setup_blog_cache_dir() { } function get_wp_cache_key( $url = false ) { - global $wp_cache_request_uri, $wp_cache_gzip_encoding, $WPSC_HTTP_HOST; + global $wp_cache_request_uri, $wp_cache_gzip_encoding, $wp_cache_br_encoding, $WPSC_HTTP_HOST; if ( ! $url ) { $url = $wp_cache_request_uri; } @@ -43,8 +51,8 @@ function wp_super_cache_init() { } function wp_cache_serve_cache_file() { - global $key, $blogcacheid, $wp_cache_request_uri, $file_prefix, $blog_cache_dir, $meta_file, $cache_file, $cache_filename, $meta_pathname, $wp_cache_gzip_encoding, $meta; - global $cache_compression, $wp_cache_slash_check, $wp_supercache_304, $wp_cache_home_path, $wp_cache_no_cache_for_get; + global $key, $blogcacheid, $wp_cache_request_uri, $file_prefix, $blog_cache_dir, $meta_file, $cache_file, $cache_filename, $meta_pathname, $wp_cache_gzip_encoding, $wp_cache_br_encoding, $meta; + global $cache_compression, $cache_compression_br, $wp_cache_slash_check, $wp_supercache_304, $wp_cache_home_path, $wp_cache_no_cache_for_get; global $wp_cache_disable_utf8, $wp_cache_mfunc_enabled, $wpsc_served_header; if ( wpsc_is_backend() ) { @@ -132,6 +140,14 @@ function wp_cache_serve_cache_file() { $cachefiledata = gzencode( file_get_contents( $file ), 6, FORCE_GZIP ); wp_cache_debug( "Fetched static page data from supercache file using PHP and gzipped it. File: $file" ); } + } elseif ( $wp_cache_br_encoding ) { + if ( file_exists( $file . '.br' ) ) { + $cachefiledata = file_get_contents( $file . '.br' ); + wp_cache_debug( "Fetched br static page data from supercache file using PHP. File: $file.br" ); + } else { + $cachefiledata = brotli_compress( file_get_contents( $file ), BROTLI_COMPRESS_LEVEL_DEFAULT, BROTLI_TEXT ); + wp_cache_debug( "Fetched static page data from supercache file using PHP and brotli'd it. File: $file" ); + } } else { $cachefiledata = file_get_contents( $file ); wp_cache_debug( "Fetched static page data from supercache file using PHP. File: $file" ); @@ -142,6 +158,9 @@ function wp_cache_serve_cache_file() { if ( $wp_cache_gzip_encoding ) { $cachefiledata = gzencode( $cachefiledata, 6, FORCE_GZIP ); wp_cache_debug( "Fetched dynamic page data from supercache file using PHP and gzipped it. File: $file" ); + } elseif ( $wp_cache_br_encoding ) { + $cachefiledata = brotli_compress( file_get_contents( $file ), BROTLI_COMPRESS_LEVEL_DEFAULT, BROTLI_TEXT ); + wp_cache_debug( "Fetched dynamic page data from supercache file using PHP and brotli'd it. File: $file" ); } else { wp_cache_debug( "Fetched dynamic page data from supercache file using PHP. File: $file" ); } @@ -171,6 +190,12 @@ function wp_cache_serve_cache_file() { } header( 'Content-Encoding: ' . $wp_cache_gzip_encoding ); header( 'Content-Length: ' . $size ); + } elseif ( $wp_cache_br_encoding ) { + if ( isset( $wpsc_served_header ) && $wpsc_served_header ) { + header( "X-WP-Super-Cache: Served supercache br file from PHP" ); + } + header( 'Content-Encoding: ' . $wp_cache_br_encoding ); + header( 'Content-Length: ' . $size ); } elseif ( $wp_supercache_304 ) { if ( isset( $wpsc_served_header ) && $wpsc_served_header ) { header( "X-WP-Super-Cache: Served supercache 304 file from PHP" ); @@ -847,6 +872,7 @@ function get_all_supercache_filenames( $dir = '' ) { foreach( $filenames as $file ) { $out[] = $file; $out[] = $file . '.gz'; + $out[] = $file . '.br'; } return $out; @@ -1959,8 +1985,8 @@ function wp_cache_maybe_dynamic( &$buffer ) { function wp_cache_get_ob(&$buffer) { global $cache_enabled, $cache_path, $cache_filename, $wp_start_time, $supercachedir; - global $new_cache, $wp_cache_meta, $cache_compression, $wp_super_cache_query; - global $wp_cache_gzip_encoding, $super_cache_enabled; + global $new_cache, $wp_cache_meta, $cache_compression, $cache_compression_br, $wp_super_cache_query; + global $wp_cache_gzip_encoding, $wp_cache_br_encoding, $super_cache_enabled; global $gzsize, $supercacheonly; global $blog_cache_dir, $wp_supercache_cache_list; global $wp_cache_not_logged_in, $cache_max_time; @@ -2078,7 +2104,7 @@ function wp_cache_get_ob(&$buffer) { return $buffer; } - $fr = $fr2 = $gz = false; + $fr = $fr2 = $gz = $br = false; // Open wp-cache cache file if ( ! $supercacheonly ) { $fr = @fopen( $tmp_wpcache_filename, 'w' ); @@ -2126,6 +2152,24 @@ function wp_cache_get_ob(&$buffer) { wp_cache_writers_exit(); return wp_cache_maybe_dynamic( $buffer ); } + } elseif ( + $cache_compression_br && + ( + ! isset( $wp_cache_mfunc_enabled ) || + $wp_cache_mfunc_enabled == 0 + ) + ) { // don't want to store compressed files if using dynamic content + $br = @fopen( $tmp_cache_filename . ".br", 'w'); + if ( !$br ) { + wp_cache_debug( 'Error. Supercache could not write to ' . str_replace( ABSPATH, '', $tmp_cache_filename ) . ".br", 1 ); + wp_cache_add_to_buffer( $buffer, "File not cached! Super Cache Couldn't write to: " . str_replace( ABSPATH, '', $tmp_cache_filename ) . ".br" ); + @fclose( $fr ); + @unlink( $tmp_wpcache_filename ); + @fclose( $fr2 ); + @unlink( $tmp_cache_filename ); + wp_cache_writers_exit(); + return wp_cache_maybe_dynamic( $buffer ); + } } } } @@ -2169,6 +2213,12 @@ function wp_cache_get_ob(&$buffer) { $gzdata = gzencode( $buffer, 6, FORCE_GZIP ); $gzsize = function_exists( 'mb_strlen' ) ? mb_strlen( $gzdata, '8bit' ) : strlen( $gzdata ); } + if ( $cache_compression_br && $wp_cache_br_encoding ) { + wp_cache_debug( 'Brotling dynamic buffer for display.', 5 ); + wp_cache_add_to_buffer( $buffer, "Compression = br" ); + $brdata = brotli_compress( $buffer, BROTLI_COMPRESS_LEVEL_DEFAULT, BROTLI_TEXT ); + $brsize = function_exists( 'mb_strlen' ) ? mb_strlen( $brdata, '8bit' ) : strlen( $brdata ); + } } else { if ( defined( 'WPSC_VARY_HEADER' ) ) { if ( WPSC_VARY_HEADER != '' ) { @@ -2194,6 +2244,18 @@ function wp_cache_get_ob(&$buffer) { wp_cache_debug( 'Writing gzipped buffer to wp-cache cache file.', 5 ); fputs($fr, '' . $gzdata); } + } elseif ( $br || $wp_cache_br_encoding ) { + wp_cache_debug( 'Brotling buffer.', 5 ); + wp_cache_add_to_buffer( $buffer, "Compression = br" ); + $brdata = brotli_compress( $buffer, BROTLI_COMPRESS_LEVEL_DEFAULT, BROTLI_TEXT ); + $brsize = function_exists( 'mb_strlen' ) ? mb_strlen( $brdata, '8bit' ) : strlen( $brdata ); + + $wp_cache_meta[ 'headers' ][ 'Content-Encoding' ] = 'Content-Encoding: ' . $wp_cache_br_encoding; + // Return uncompressed data & store compressed for later use + if ( $fr ) { + wp_cache_debug( 'Writing brotli\d buffer to wp-cache cache file.', 5 ); + fputs($fr, '' . $brdata); + } } else { // no compression if ( $fr ) { wp_cache_debug( 'Writing non-gzipped buffer to wp-cache cache file.' ); @@ -2209,6 +2271,10 @@ function wp_cache_get_ob(&$buffer) { wp_cache_debug( 'Writing gzipped buffer to supercache file.' ); fwrite($gz, $gzdata ); } + if ( isset( $brdata ) && $br ) { + wp_cache_debug( 'Writing brotli\'d buffer to supercache file.' ); + fwrite($br, $brdata ); + } } $new_cache = true; @@ -2267,6 +2333,20 @@ function wp_cache_get_ob(&$buffer) { $added_cache = 1; } } + if ( $br ) { + fclose( $br ); + if ( filesize( $tmp_cache_filename . '.br' ) == 0 ) { + wp_cache_debug( "Warning! The file {$tmp_cache_filename}.br was empty. Did not rename to {$cache_fname}.br", 5 ); + @unlink( $tmp_cache_filename . '.br' ); + } else { + if ( ! @rename( $tmp_cache_filename . '.br', $cache_fname . '.br' ) ) { + @unlink( $cache_fname . '.br' ); + @rename( $tmp_cache_filename . '.br', $cache_fname . '.br' ); + } + wp_cache_debug( "Renamed temp supercache br file to {$cache_fname}.br", 5 ); + $added_cache = 1; + } + } if ( $added_cache && isset( $wp_supercache_cache_list ) && $wp_supercache_cache_list ) { update_option( 'wpsupercache_count', ( get_option( 'wpsupercache_count' ) + 1 ) ); @@ -2294,6 +2374,23 @@ function wp_cache_get_ob(&$buffer) { } header( 'Content-Length: ' . $gzsize ); return $gzdata; + } elseif ( !headers_sent() && $wp_cache_br_encoding && $brdata) { + wp_cache_debug( 'Writing br content headers. Sending buffer to browser', 5 ); + header( 'Content-Encoding: ' . $wp_cache_br_encoding ); + if ( defined( 'WPSC_VARY_HEADER' ) ) { + if ( WPSC_VARY_HEADER != '' ) { + $vary_header = WPSC_VARY_HEADER; + } else { + $vary_header = ''; + } + } else { + $vary_header = 'Accept-Encoding, Cookie'; + } + if ( $vary_header ) { + header( 'Vary: ' . $vary_header ); + } + header( 'Content-Length: ' . $brsize ); + return $brdata; } else { wp_cache_debug( 'Sending buffer to browser', 5 ); return $buffer; @@ -2532,7 +2629,7 @@ function wp_cache_phase2_clean_expired( $file_prefix, $force = false ) { } function wp_cache_shutdown_callback() { - global $cache_max_time, $meta_file, $new_cache, $wp_cache_meta, $known_headers, $blog_id, $wp_cache_gzip_encoding, $supercacheonly, $blog_cache_dir; + global $cache_max_time, $meta_file, $new_cache, $wp_cache_meta, $known_headers, $blog_id, $wp_cache_gzip_encoding, $wp_cache_br_encoding, $supercacheonly, $blog_cache_dir; global $wp_cache_request_uri, $wp_cache_key, $cache_enabled, $wp_cache_blog_charset, $wp_cache_not_logged_in; global $WPSC_HTTP_HOST, $wp_super_cache_query; diff --git a/wp-cache.php b/wp-cache.php index 753bea00b..f665825e8 100644 --- a/wp-cache.php +++ b/wp-cache.php @@ -74,7 +74,7 @@ function wpsc_init() { */ global $super_cache_enabled, $cache_enabled, $wp_cache_mod_rewrite, $wp_cache_home_path, $cache_path, $file_prefix; global $wp_cache_mutex_disabled, $mutex_filename, $sem_id, $wp_super_cache_late_init; -global $cache_compression, $cache_max_time, $wp_cache_shutdown_gc, $cache_rebuild_files; +global $cache_compression, $cache_compression_br, $cache_max_time, $wp_cache_shutdown_gc, $cache_rebuild_files; global $wp_super_cache_debug, $wp_super_cache_advanced_debug, $wp_cache_debug_level, $wp_cache_debug_to_file; global $wp_cache_debug_log, $wp_cache_debug_ip, $wp_cache_debug_username, $wp_cache_debug_email; global $cache_time_interval, $cache_scheduled_time, $cache_schedule_interval, $cache_schedule_type, $cache_gc_email_me; @@ -530,7 +530,7 @@ function admin_bar_delete_page() { } function wp_cache_manager_updates() { - global $wp_cache_mobile_enabled, $wp_cache_mfunc_enabled, $wp_supercache_cache_list, $wp_cache_config_file, $wp_cache_clear_on_post_edit, $cache_rebuild_files, $wp_cache_mutex_disabled, $wp_cache_not_logged_in, $wp_cache_make_known_anon, $cache_path, $wp_cache_refresh_single_only, $cache_compression, $wp_cache_mod_rewrite, $wp_supercache_304, $wp_super_cache_late_init, $wp_cache_front_page_checks, $cache_page_secret, $wp_cache_disable_utf8, $wp_cache_no_cache_for_get; + global $wp_cache_mobile_enabled, $wp_cache_mfunc_enabled, $wp_supercache_cache_list, $wp_cache_config_file, $wp_cache_clear_on_post_edit, $cache_rebuild_files, $wp_cache_mutex_disabled, $wp_cache_not_logged_in, $wp_cache_make_known_anon, $cache_path, $wp_cache_refresh_single_only, $cache_compression, $cache_compression_br, $wp_cache_mod_rewrite, $wp_supercache_304, $wp_super_cache_late_init, $wp_cache_front_page_checks, $cache_page_secret, $wp_cache_disable_utf8, $wp_cache_no_cache_for_get; global $cache_schedule_type, $cache_max_time, $cache_time_interval, $wp_cache_shutdown_gc, $wpsc_save_headers; if ( !wpsupercache_site_admin() ) @@ -738,16 +738,19 @@ function wp_cache_manager_updates() { if ( defined( 'WPSC_DISABLE_COMPRESSION' ) ) { $cache_compression = 0; + $cache_compression_br = 0; wp_cache_replace_line('^ *\$cache_compression', "\$cache_compression = " . $cache_compression . ";", $wp_cache_config_file); + wp_cache_replace_line('^ *\$cache_compression_br', "\$cache_compression_br = " . $cache_compression_br . ";", $wp_cache_config_file); } else { - if ( isset( $_POST[ 'cache_compression' ] ) ) { - $new_cache_compression = 1; - } else { - $new_cache_compression = 0; - } if ( 1 == ini_get( 'zlib.output_compression' ) || "on" == strtolower( ini_get( 'zlib.output_compression' ) ) ) { echo '
' . __( "Warning! You attempted to enable compression but zlib.output_compression is enabled. See #21 in the Troubleshooting section of the readme file.", 'wp-super-cache' ) . '
'; } else { + // Moved these here, no point in setting stuff if we're not gonna enter here anyway. + if ( isset( $_POST[ 'cache_compression' ] ) ) { + $new_cache_compression = 1; + } else { + $new_cache_compression = 0; + } if ( $new_cache_compression != $cache_compression ) { $cache_compression = $new_cache_compression; wp_cache_replace_line('^ *\$cache_compression', "\$cache_compression = " . $cache_compression . ";", $wp_cache_config_file); @@ -755,6 +758,20 @@ function wp_cache_manager_updates() { prune_super_cache( $cache_path, true ); delete_option( 'super_cache_meta' ); } + + // Brotli + if ( isset( $_POST[ 'cache_compression_br' ] ) ) { + $new_cache_compression_br = 1; + } else { + $new_cache_compression_br = 0; + } + if ( $new_cache_compression_br != $cache_compression_br ) { + $cache_compression_br = $new_cache_compression_br; + wp_cache_replace_line('^ *\$cache_compression_br', "\$cache_compression_br = " . $cache_compression_br . ";", $wp_cache_config_file); + if ( function_exists( 'prune_super_cache' ) ) + prune_super_cache( $cache_path, true ); + delete_option( 'super_cache_meta' ); + } } } } @@ -763,7 +780,7 @@ function wp_cache_manager_updates() { add_action( 'admin_init', 'wp_cache_manager_updates' ); function wp_cache_manager() { - global $wp_cache_config_file, $valid_nonce, $supercachedir, $cache_path, $cache_enabled, $cache_compression, $super_cache_enabled; + global $wp_cache_config_file, $valid_nonce, $supercachedir, $cache_path, $cache_enabled, $cache_compression, $cache_compression_br, $super_cache_enabled; global $wp_cache_clear_on_post_edit, $cache_rebuild_files, $wp_cache_mutex_disabled, $wp_cache_mobile_enabled, $wp_cache_mobile_browsers, $wp_cache_no_cache_for_get; global $wp_cache_not_logged_in, $wp_cache_make_known_anon, $wp_supercache_cache_list, $cache_page_secret; global $wp_super_cache_front_page_check, $wp_cache_refresh_single_only, $wp_cache_mobile_prefixes; @@ -1096,6 +1113,12 @@ function toggleLayer( whichLayer ) {

+ +
+ +
+
+
@@ -2708,7 +2731,7 @@ function wp_cache_format_fsize( $fsize ) { } function wp_cache_regenerate_cache_file_stats() { - global $cache_compression, $supercachedir, $file_prefix, $wp_cache_preload_on, $cache_max_time; + global $cache_compression, $cache_compression_br, $supercachedir, $file_prefix, $wp_cache_preload_on, $cache_max_time; if ( $supercachedir == '' ) $supercachedir = get_supercache_dir(); @@ -2737,7 +2760,7 @@ function wp_cache_regenerate_cache_file_stats() { $sizes[ $cache_type ][ $status ] = $cached_list; } } - if ( $cache_compression ) { + if ( $cache_compression || $cache_compression_br ) { $sizes[ 'supercache' ][ 'cached' ] = intval( $sizes[ 'supercache' ][ 'cached' ] / 2 ); $sizes[ 'supercache' ][ 'expired' ] = intval( $sizes[ 'supercache' ][ 'expired' ] / 2 ); } From f8ad376672129e82a7b3f85cb2e65da0499507d3 Mon Sep 17 00:00:00 2001 From: Stathis Oureilidis Date: Fri, 27 Nov 2020 16:05:44 +0200 Subject: [PATCH 2/3] Changes --- wp-cache.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/wp-cache.php b/wp-cache.php index f665825e8..cf1affc07 100644 --- a/wp-cache.php +++ b/wp-cache.php @@ -742,15 +742,21 @@ function wp_cache_manager_updates() { wp_cache_replace_line('^ *\$cache_compression', "\$cache_compression = " . $cache_compression . ";", $wp_cache_config_file); wp_cache_replace_line('^ *\$cache_compression_br', "\$cache_compression_br = " . $cache_compression_br . ";", $wp_cache_config_file); } else { + if ( isset( $_POST[ 'cache_compression' ] ) ) { + $new_cache_compression = 1; + } else { + $new_cache_compression = 0; + } + // Brotli + if ( isset( $_POST[ 'cache_compression_br' ] ) ) { + $new_cache_compression_br = 1; + } else { + $new_cache_compression_br = 0; + } + if ( 1 == ini_get( 'zlib.output_compression' ) || "on" == strtolower( ini_get( 'zlib.output_compression' ) ) ) { echo '
' . __( "Warning! You attempted to enable compression but zlib.output_compression is enabled. See #21 in the Troubleshooting section of the readme file.", 'wp-super-cache' ) . '
'; } else { - // Moved these here, no point in setting stuff if we're not gonna enter here anyway. - if ( isset( $_POST[ 'cache_compression' ] ) ) { - $new_cache_compression = 1; - } else { - $new_cache_compression = 0; - } if ( $new_cache_compression != $cache_compression ) { $cache_compression = $new_cache_compression; wp_cache_replace_line('^ *\$cache_compression', "\$cache_compression = " . $cache_compression . ";", $wp_cache_config_file); @@ -758,13 +764,7 @@ function wp_cache_manager_updates() { prune_super_cache( $cache_path, true ); delete_option( 'super_cache_meta' ); } - // Brotli - if ( isset( $_POST[ 'cache_compression_br' ] ) ) { - $new_cache_compression_br = 1; - } else { - $new_cache_compression_br = 0; - } if ( $new_cache_compression_br != $cache_compression_br ) { $cache_compression_br = $new_cache_compression_br; wp_cache_replace_line('^ *\$cache_compression_br', "\$cache_compression_br = " . $cache_compression_br . ";", $wp_cache_config_file); From f01250e87085fb3bc67791602a768a7a777c6286 Mon Sep 17 00:00:00 2001 From: Stathis Oureilidis Date: Fri, 27 Nov 2020 16:12:56 +0200 Subject: [PATCH 3/3] FASTPATH ver --- wp-cache.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wp-cache.php b/wp-cache.php index 5299ed60e..59027ec60 100644 --- a/wp-cache.php +++ b/wp-cache.php @@ -1,10 +1,10 @@