PluginProbe
BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript / 4.1.16
BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript v4.1.16
4.1.16 4.1.15 4.1.14 4.1.13 4.1.12 4.1.11 4.1.10 4.0.30 4.0.29 4.0.28 4.0.27 4.0.26 4.0.24 4.0.25 4.0.23 4.0.22 4.0.21 4.0.19 4.0.18 4.0.17 4.0.16 1.9.3 1.9.4 1.9.5 1.9.6 All 170 releases
searchpro / inc / common-functions.php

common-functions.php in BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript 4.1.16, at inc/common-functions.php

237 lines 8.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 function bwp_pass_cookie_requirement() {
4 $berqconfigs = berqConfigs::getInstance();
5 $configs = $berqconfigs->get_configs();
6 $default = ['berqwpnocache', 'wp-postpass', 'comment_author', 'woocommerce_cart_hash', 'edd_items_in_cart'];
7 $excluded_cookies = array_merge($configs['exclude_cookies'], $default);
8
9 if (!empty($excluded_cookies)) {
10 foreach ($excluded_cookies as $cookie_id) {
11
12 // Skip if empty
13 if (empty($cookie_id)) {
14 continue;
15 }
16
17 foreach ($_COOKIE as $key => $value) {
18 if (strpos($key, $cookie_id) === 0) {
19 return false;
20 }
21 }
22 }
23 }
24
25 return true;
26 }
27
28 function bwp_request_is_https() {
29 if (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') {
30 return true;
31 }
32
33 // Reverse proxy / load balancer terminating TLS upstream
34 if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
35 // may be a comma-separated chain: "https,http" — first hop is the client
36 $proto = strtolower(trim(explode(',', $_SERVER['HTTP_X_FORWARDED_PROTO'])[0]));
37 if ($proto === 'https') {
38 return true;
39 }
40 }
41
42 if (!empty($_SERVER['HTTP_X_FORWARDED_SSL']) && strtolower($_SERVER['HTTP_X_FORWARDED_SSL']) === 'on') {
43 return true;
44 }
45
46 if (!empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) === 'on') {
47 return true;
48 }
49
50 if (!empty($_SERVER['SERVER_PORT']) && (int) $_SERVER['SERVER_PORT'] === 443) {
51 return true;
52 }
53
54 return false;
55 }
56
57 function bwp_get_request_url() {
58
59 $scheme = 'http://';
60
61 if (bwp_request_is_https()) {
62 $scheme = 'https://';
63 } elseif (function_exists('wp_parse_url') && function_exists('get_option')) {
64 $scheme = (wp_parse_url(get_option('home'), PHP_URL_SCHEME) === 'https') ? 'https://' : 'http://';
65 }
66
67 $host = isset($_SERVER['HTTP_HOST']) ? strip_tags(stripslashes($_SERVER['HTTP_HOST'])) : 'localhost';
68 $uri = isset($_SERVER['REQUEST_URI']) ? strip_tags(stripslashes($_SERVER['REQUEST_URI'])) : '/';
69 $url = $scheme . $host . $uri;
70 return strtolower($url);
71 }
72
73 // function bwp_build_cache_path($url) {
74 // $parts = parse_url($url);
75
76 // $host = $parts['host'] ?? '';
77 // $path = $parts['path'] ?? '/';
78
79 // // normalize
80 // $path = '/' . ltrim($path, '/');
81 // $path = rtrim($path, '/');
82
83 // if ($path === '') {
84 // $path = '/';
85 // }
86
87 // // sanitize
88 // $host = preg_replace('#[^a-zA-Z0-9\.\-]#', '', $host);
89 // $path = preg_replace('#[^a-zA-Z0-9/_-]#', '', $path);
90
91 // return $host . $path;
92 // }
93
94 function bwp_build_cache_path($url) {
95 $parts = parse_url($url);
96 $host = $parts['host'] ?? '';
97 $path = $parts['path'] ?? '/';
98 $query = $parts['query'] ?? '';
99
100 // normalize path
101 $path = '/' . ltrim($path, '/');
102 $path = rtrim($path, '/');
103 if ($path === '') {
104 $path = '/';
105 }
106
107 // sanitize host
108 $host = preg_replace('#[^a-zA-Z0-9\.\-]#', '', $host);
109
110 // Normalize percent-encoded chars to raw UTF-8, then strip only chars that
111 // are unsafe on filesystems (null bytes, path traversal sequences).
112 $path = urldecode($path);
113 $path = str_replace("\0", '', $path);
114 $path = preg_replace('#\.\.+#', '', $path);
115 $path = preg_replace('#[<>:"\\\\|?*]#', '', $path);
116
117 if ($query === '') {
118 return $path === '/' ? $host : $host . $path;
119 }
120
121 // normalize query param order so ?b=2&a=1 and ?a=1&b=2 hit the same cache
122 parse_str($query, $params);
123 ksort($params);
124 $normalized_query = http_build_query($params);
125
126 // hash it — query strings can contain anything and be very long
127 $query_hash = substr(md5($normalized_query), 0, 12);
128
129 return $host . $path . '/q-' . $query_hash;
130 }
131
132 function bwp_serve_advanced_cache($serve_from = 'plugin') {
133
134 if (php_sapi_name() === 'cli' || (defined('WP_CLI') && WP_CLI)) {
135 return;
136 }
137
138 if ( strpos( $_SERVER["REQUEST_URI"], "berqwp-ping" ) !== false ) {
139 echo "PONG";
140 exit();
141 }
142
143 if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'GET' && !bwp_is_user_logged_in() && !bwp_is_ajax() && !berqDetectCrawler::is_crawler() && bwp_pass_cookie_requirement()) {
144
145 $berqconfigs = berqConfigs::getInstance();
146 $configs = $berqconfigs->get_configs();
147 $url = bwp_get_request_url();
148 $url = @dropin_remove_ignore_params($url);
149 $cache_key = md5($url);
150 $cache_directory = WP_CONTENT_DIR . '/cache/berqwp/html/';
151 if (defined('MULTISITE') && MULTISITE) {
152 $blog_id = berqConfigs::detect_blog_id_from_request();
153 $cache_directory .= 'site-' . $blog_id . '/';
154 }
155 $cache_file = $cache_directory . $cache_key . '.html';
156 $cache_file_gz = $cache_directory . $cache_key . '.gz';
157 $cache_file_gz = $cache_directory . bwp_build_cache_path($url) . '/index.html.gz';
158 $cache_file = $cache_file_gz;
159 $cache_max_life = file_exists($cache_file) ? @filemtime($cache_file) + $configs['cache_lifespan'] : null;
160 // $compression_enabled = $configs['page_compression'] === true;
161 $compression_enabled = true;
162 $accept_encoding = $_SERVER['HTTP_ACCEPT_ENCODING'] ?? '';
163 $supports_gzip = strpos($accept_encoding, 'gzip') !== false;
164 $domain = isset($_SERVER['HTTP_HOST']) ? strip_tags(stripslashes($_SERVER['HTTP_HOST'])) : '';
165
166 if (berqwp_dropin_is_page_url_excluded($url)) {
167 return;
168 }
169
170
171 if (file_exists($cache_file) && $cache_max_life > time()) {
172 $file_content = @file_get_contents($cache_file);
173
174 if (!isset($_GET['creating_cache']) && file_exists($cache_file)) {
175
176 if (strpos($file_content, "Optimized with BerqWP's instant cache") !== false && (filemtime($cache_file) + DAY_IN_SECONDS) < time()) {
177 return;
178 }
179
180 // Prepare gzip cache file
181 if ($compression_enabled && file_exists($cache_file_gz)) {
182 $cache_file = $cache_file_gz;
183 // header('Content-Encoding: gzip');
184 header_remove('Content-Encoding');
185 }
186
187 $lastModified = filemtime($cache_file);
188 $etag = md5_file($cache_file);
189 header('ETag: ' . $etag);
190 header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastModified) . ' GMT');
191 header('X-File-Size: ' . filesize($cache_file), true);
192 header('Content-Type: text/html; charset=utf-8');
193 header("X-served: $serve_from");
194 header("X-BerqWP-Cache: HIT");
195 // header('Vary: Cookie');
196
197 // Check if the client has a cached copy and if it's still valid using Last-Modified
198 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)) {
199 // The client's cache is still valid based on Last-Modified, respond with a 304 Not Modified
200 header('HTTP/1.1 304 Not Modified');
201 // header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
202 // header("Expires: 0");
203 // header('Cache-Control: no-cache, must-revalidate');
204 header('Cache-Control: public, max-age=600, s-maxage=2592000, stale-while-revalidate=86400', true);
205 header('cdn-cache-control: max-age=2592000');
206 header("Cache-Tag: $domain");
207 exit();
208
209 }
210
211 // Prevent PHP/Apache from re-compressing the already-gzipped cache file
212 if (ini_get('zlib.output_compression')) {
213 ini_set('zlib.output_compression', 'Off');
214 }
215
216 while (ob_get_level()) {
217 ob_end_clean();
218 }
219
220 // header('Cache-Control: public, max-age=0, s-maxage=3600, must-revalidate', true);
221 // header('Cache-Control: public, max-age=60, s-maxage=3600, stale-while-revalidate=60, must-revalidate', true);
222 header('Cache-Control: public, max-age=600, s-maxage=2592000, stale-while-revalidate=86400', true);
223 header('cdn-cache-control: max-age=2592000');
224 header("Cache-Tag: $domain");
225 // header("Content-Security-Policy: script-src 'self' blob: 'unsafe-inline'");
226 header('Vary: Accept-Encoding, Cookie');
227 header('Content-Encoding: gzip', true);
228 header('Content-Length: ' . filesize($cache_file), true);
229 readfile($cache_file);
230 exit();
231 }
232
233 }
234
235 }
236 }
237