| @@ -91,12 +91,20 @@ | ||
| 91 | 91 | |
| 92 | 92 | // Apache htaccess cache rules (skip on LiteSpeed — remove any existing rules) |
| 93 | 93 | add_action('berqwp_activate_plugin', 'bwp_write_htaccess_rules'); |
| 94 | 94 | add_action('berqwp_flush_all_cache', 'bwp_write_htaccess_rules'); |
| 95 | + add_action('berqwp_flush_all_cache', 'bwp_delete_php_files_in_cache'); | |
| 95 | 96 | add_action('berqwp_deactivate_plugin', 'bwp_remove_htaccess_rules'); |
| 97 | + | |
| 98 | + // Keep the dropin's cached permalink convention in sync with WordPress | |
| 99 | + add_action('init', 'bwp_sync_permalink_config'); | |
| 100 | + add_action('update_option_permalink_structure', 'bwp_sync_permalink_config'); | |
| 101 | + add_action('berqwp_activate_plugin', 'bwp_sync_permalink_config'); | |
| 102 | + | |
| 96 | 103 | if (bwp_is_openlitespeed_server()) { |
| 97 | 104 | add_action('berqwp_activate_plugin', 'bwp_remove_htaccess_rules'); |
| 98 | 105 | } |
| 106 | + | |
| 99 | 107 | add_action('berqwp_on_update_sandbox_mode', 'bwp_sync_htaccess_on_sandbox_change'); |
| 100 | 108 | |
| 101 | 109 | // Clear queue list on cloud |
| 102 | 110 | add_action('berqwp_deactivate_plugin', 'berqwp_clear_cache_queue'); |
| @@ -179,8 +187,11 @@ | ||
| 179 | 187 | $berq_log->info("Processing updates"); |
| 180 | 188 | |
| 181 | 189 | self::stale_cloud_assets(); |
| 182 | 190 | $this->purge_critical_css_cache(); |
| 191 | + | |
| 192 | + // trigger cache warmup | |
| 193 | + do_action('berqwp_cache_warmup'); | |
| 183 | 194 | |
| 184 | 195 | } |
| 185 | 196 | |
| 186 | 197 | static function stale_cloud_assets() { |
| @@ -897,22 +908,27 @@ | ||
| 897 | 908 | // berqHeartbeat::add_queue($page_url); |
| 898 | 909 | warmup_cache_by_url($page_url); |
| 899 | 910 | } |
| 900 | 911 | |
| 912 | + static function miss_cache_headers() { | |
| 913 | + header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0', true); | |
| 914 | + header('CDN-Cache-Control: no-store', true); // Cloudflare | |
| 915 | + header('Surrogate-Control: no-store', true); // Varnish | |
| 916 | + header('X-Accel-Expires: 0', true); // Nginx FastCGI | |
| 917 | + header("X-BerqWP-Cache: MISS"); | |
| 918 | + } | |
| 919 | + | |
| 901 | 920 | function html_cache() |
| 902 | 921 | { |
| 903 | 922 | |
| 904 | 923 | // Bypass cache for Photon |
| 905 | 924 | if (!empty($_COOKIE['berqwpnocache'])) { |
| 906 | - header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0', true); | |
| 907 | - header('CDN-Cache-Control: no-store', true); // Cloudflare | |
| 908 | - header('Surrogate-Control: no-store', true); // Varnish | |
| 909 | - header('X-Accel-Expires: 0', true); // Nginx FastCGI | |
| 910 | - | |
| 925 | + self::miss_cache_headers(); | |
| 911 | 926 | return; |
| 912 | 927 | } |
| 913 | 928 | |
| 914 | 929 | if (!self::should_cache()) { |
| 930 | + self::miss_cache_headers(); | |
| 915 | 931 | return; |
| 916 | 932 | } |
| 917 | 933 | |
| 918 | 934 | $page_url = self::get_page_url(); |
| @@ -917,20 +933,33 @@ | ||
| 917 | 933 | |
| 918 | 934 | $page_url = self::get_page_url(); |
| 919 | 935 | |
| 920 | 936 | if (empty($page_url)) { |
| 937 | + self::miss_cache_headers(); | |
| 921 | 938 | return; |
| 922 | 939 | } |
| 923 | 940 | |
| 924 | 941 | // Disable cache for unknown query parameters |
| 925 | 942 | if (strpos($page_url, '?') !== false) { |
| 943 | + self::miss_cache_headers(); | |
| 926 | 944 | return; |
| 927 | 945 | } |
| 928 | 946 | |
| 947 | + | |
| 948 | + // Redirect non-canonical URLs (wrong trailing slash) the same way WordPress would, | |
| 949 | + // before ever touching the cache — works for both trailing-slash and non-trailing-slash | |
| 950 | + // permalink structures. | |
| 951 | + $canonical_url = bwp_canonicalize_page_url($page_url); | |
| 952 | + if ($canonical_url !== $page_url) { | |
| 953 | + wp_safe_redirect($canonical_url, 301); | |
| 954 | + exit(); | |
| 955 | + } | |
| 956 | + | |
| 929 | 957 | if (is_singular()) { |
| 930 | 958 | $post_type = get_post_type(); |
| 931 | 959 | |
| 932 | 960 | if (empty($post_type) || !in_array($post_type, get_option('berqwp_optimize_post_types'))) { |
| 961 | + self::miss_cache_headers(); | |
| 933 | 962 | return; |
| 934 | 963 | } |
| 935 | 964 | } elseif (is_archive()) { |
| 936 | 965 | $queried_object = get_queried_object(); |
| @@ -938,8 +967,9 @@ | ||
| 938 | 967 | if ($queried_object instanceof WP_Term && !empty($queried_object->taxonomy)) { |
| 939 | 968 | $current_taxonomy = $queried_object->taxonomy; |
| 940 | 969 | |
| 941 | 970 | if (!in_array($current_taxonomy, get_option('berqwp_optimize_taxonomies'))) { |
| 971 | + self::miss_cache_headers(); | |
| 942 | 972 | return; |
| 943 | 973 | } |
| 944 | 974 | } |
| 945 | 975 | } |
| @@ -947,8 +977,9 @@ | ||
| 947 | 977 | |
| 948 | 978 | $status_code = http_response_code(); |
| 949 | 979 | |
| 950 | 980 | if ($status_code !== 200) { |
| 981 | + self::miss_cache_headers(); | |
| 951 | 982 | return; |
| 952 | 983 | } |
| 953 | 984 | |
| 954 | 985 | $berqconfigs = berqConfigs::getInstance(); |
| @@ -969,15 +1000,21 @@ | ||
| 969 | 1000 | header('X-File-Size: ' . filesize($cache_file), true); |
| 970 | 1001 | header('Content-Type: text/html; charset=utf-8'); |
| 971 | 1002 | header("X-served: WP Hook"); |
| 972 | 1003 | header('Vary: Accept-Encoding, Cookie'); |
| 1004 | + header("X-BerqWP-Cache: HIT"); | |
| 973 | 1005 | |
| 974 | 1006 | if ((isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $lastModified) || (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] === $etag)) { |
| 975 | 1007 | // The client's cache is still valid based on Last-Modified, respond with a 304 Not Modified |
| 976 | 1008 | header('HTTP/1.1 304 Not Modified'); |
| 977 | 1009 | // header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT'); |
| 978 | - header("Expires: 0"); | |
| 979 | - header('Cache-Control: no-cache, must-revalidate'); | |
| 1010 | + // header("Expires: 0"); | |
| 1011 | + // header('Cache-Control: no-cache, must-revalidate'); | |
| 1012 | + | |
| 1013 | + header('Cache-Control: public, max-age=600, s-maxage=2592000, stale-while-revalidate=86400', true); | |
| 1014 | + header('cdn-cache-control: max-age=2592000'); | |
| 1015 | + header('Cache-Tag: ' . wp_parse_url(home_url())['host']); | |
| 1016 | + | |
| 980 | 1017 | exit(); |
| 981 | 1018 | } |
| 982 | 1019 | |
| 983 | 1020 | // Prevent PHP/Apache from re-compressing the already-gzipped cache file |
| @@ -983,14 +1020,16 @@ | ||
| 983 | 1020 | // Prevent PHP/Apache from re-compressing the already-gzipped cache file |
| 984 | 1021 | if (ini_get('zlib.output_compression')) { |
| 985 | 1022 | ini_set('zlib.output_compression', 'Off'); |
| 986 | 1023 | } |
| 987 | - | |
| 1024 | + | |
| 988 | 1025 | while (ob_get_level()) { |
| 989 | 1026 | ob_end_clean(); |
| 990 | 1027 | } |
| 991 | 1028 | |
| 992 | - header('Cache-Control: public, max-age=0, s-maxage=3600, must-revalidate', true); | |
| 1029 | + header('Cache-Control: public, max-age=600, s-maxage=2592000, stale-while-revalidate=86400', true); | |
| 1030 | + header('cdn-cache-control: max-age=2592000'); | |
| 1031 | + header('Cache-Tag: ' . wp_parse_url(home_url())['host']); | |
| 993 | 1032 | // header("Content-Security-Policy: script-src 'self' blob: 'unsafe-inline'"); |
| 994 | 1033 | header('Content-Encoding: gzip', true); |
| 995 | 1034 | header('Content-Length: ' . filesize($cache_file), true); |
| 996 | 1035 | readfile($cache_file); |
| @@ -996,12 +1035,9 @@ | ||
| 996 | 1035 | readfile($cache_file); |
| 997 | 1036 | exit(); |
| 998 | 1037 | } |
| 999 | 1038 | |
| 1000 | - header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); | |
| 1001 | - header('CDN-Cache-Control: no-store'); // Cloudflare | |
| 1002 | - header('Surrogate-Control: no-store'); // Varnish | |
| 1003 | - header('X-Accel-Expires: 0'); // Nginx FastCGI | |
| 1039 | + self::miss_cache_headers(); | |
| 1004 | 1040 | |
| 1005 | 1041 | self::purge_page($page_url); |
| 1006 | 1042 | |
| 1007 | 1043 | if (!berqwp_can_use_cloud()) { |