PluginProbe
BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript / 4.1.13
BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript v4.1.13
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.13, at inc/common-functions.php

232 lines 8.7 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 (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'GET' && !bwp_is_user_logged_in() && !bwp_is_ajax() && !berqDetectCrawler::is_crawler() && bwp_pass_cookie_requirement()) {
139
140 $berqconfigs = berqConfigs::getInstance();
141 $configs = $berqconfigs->get_configs();
142 $url = bwp_get_request_url();
143 $url = @dropin_remove_ignore_params($url);
144 $cache_key = md5($url);
145 $cache_directory = WP_CONTENT_DIR . '/cache/berqwp/html/';
146 if (defined('MULTISITE') && MULTISITE) {
147 $blog_id = berqConfigs::detect_blog_id_from_request();
148 $cache_directory .= 'site-' . $blog_id . '/';
149 }
150 $cache_file = $cache_directory . $cache_key . '.html';
151 $cache_file_gz = $cache_directory . $cache_key . '.gz';
152 $cache_file_gz = $cache_directory . bwp_build_cache_path($url) . '/index.html.gz';
153 $cache_file = $cache_file_gz;
154 $cache_max_life = file_exists($cache_file) ? @filemtime($cache_file) + $configs['cache_lifespan'] : null;
155 // $compression_enabled = $configs['page_compression'] === true;
156 $compression_enabled = true;
157 $accept_encoding = $_SERVER['HTTP_ACCEPT_ENCODING'] ?? '';
158 $supports_gzip = strpos($accept_encoding, 'gzip') !== false;
159 $domain = isset($_SERVER['HTTP_HOST']) ? strip_tags(stripslashes($_SERVER['HTTP_HOST'])) : '';
160
161 if (berqwp_dropin_is_page_url_excluded($url)) {
162 return;
163 }
164
165
166 if (file_exists($cache_file) && $cache_max_life > time()) {
167 $file_content = @file_get_contents($cache_file);
168
169 if (!isset($_GET['creating_cache']) && file_exists($cache_file)) {
170
171 if (strpos($file_content, "Optimized with BerqWP's instant cache") !== false && (filemtime($cache_file) + DAY_IN_SECONDS) < time()) {
172 return;
173 }
174
175 // Prepare gzip cache file
176 if ($compression_enabled && file_exists($cache_file_gz)) {
177 $cache_file = $cache_file_gz;
178 // header('Content-Encoding: gzip');
179 header_remove('Content-Encoding');
180 }
181
182 $lastModified = filemtime($cache_file);
183 $etag = md5_file($cache_file);
184 header('ETag: ' . $etag);
185 header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastModified) . ' GMT');
186 header('X-File-Size: ' . filesize($cache_file), true);
187 header('Content-Type: text/html; charset=utf-8');
188 header("X-served: $serve_from");
189 header("X-BerqWP-Cache: HIT");
190 // header('Vary: Cookie');
191
192 // Check if the client has a cached copy and if it's still valid using Last-Modified
193 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)) {
194 // The client's cache is still valid based on Last-Modified, respond with a 304 Not Modified
195 header('HTTP/1.1 304 Not Modified');
196 // header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
197 // header("Expires: 0");
198 // header('Cache-Control: no-cache, must-revalidate');
199 header('Cache-Control: public, max-age=600, s-maxage=2592000, stale-while-revalidate=86400', true);
200 header('cdn-cache-control: max-age=2592000');
201 header("Cache-Tag: $domain");
202 exit();
203
204 }
205
206 // Prevent PHP/Apache from re-compressing the already-gzipped cache file
207 if (ini_get('zlib.output_compression')) {
208 ini_set('zlib.output_compression', 'Off');
209 }
210
211 while (ob_get_level()) {
212 ob_end_clean();
213 }
214
215 // header('Cache-Control: public, max-age=0, s-maxage=3600, must-revalidate', true);
216 // header('Cache-Control: public, max-age=60, s-maxage=3600, stale-while-revalidate=60, must-revalidate', true);
217 header('Cache-Control: public, max-age=600, s-maxage=2592000, stale-while-revalidate=86400', true);
218 header('cdn-cache-control: max-age=2592000');
219 header("Cache-Tag: $domain");
220 // header("Content-Security-Policy: script-src 'self' blob: 'unsafe-inline'");
221 header('Vary: Accept-Encoding, Cookie');
222 header('Content-Encoding: gzip', true);
223 header('Content-Length: ' . filesize($cache_file), true);
224 readfile($cache_file);
225 exit();
226 }
227
228 }
229
230 }
231 }
232