PluginProbe ʕ •ᴥ•ʔ
NitroPack – Performance, Page Speed & Cache Plugin for Core Web Vitals, CDN & Image Optimization / 1.5.13
NitroPack – Performance, Page Speed & Cache Plugin for Core Web Vitals, CDN & Image Optimization v1.5.13
1.19.8 1.19.7 1.19.6 1.19.5 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.11.0 1.12.0 1.13.0 1.14.0 1.15.0 1.15.1 1.15.2 1.15.3 1.16.0 1.16.1 1.16.2 1.16.3 1.16.4 1.16.5 1.16.6 1.16.7 1.16.8 1.17.0 1.17.6 1.17.7 1.17.8 1.17.9 1.18.0 1.18.1 1.18.2 1.18.3 1.18.4 1.18.5 1.18.6 1.18.7 1.18.8 1.18.9 1.19.0 1.19.1 1.19.2 1.19.3 1.19.4 1.3.19 1.3.20 1.4.0 1.4.1 1.5.0 1.5.1 1.5.10 1.5.11 1.5.12 1.5.13 1.5.14 1.5.15 1.5.16 1.5.17 1.5.18 1.5.19 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.7.0 1.7.1 1.8.0 1.8.1 1.8.3 1.9.0 1.9.1 1.9.2
nitropack / classes / Integration / Server / LiteSpeed.php
nitropack / classes / Integration / Server Last commit date
Cloudflare.php 4 years ago Fastly.php 4 years ago LiteSpeed.php 3 years ago Sucuri.php 4 years ago
LiteSpeed.php
159 lines
1 <?php
2
3 namespace NitroPack\Integration\Server;
4 use NitroPack\WordPress\NitroPack;
5 use NitroPack\Url;
6 use NitroPack\SDK\Device;
7 use NitroPack\Integration\Hosting\WPX;
8
9 class LiteSpeed {
10 const STAGE = "very_early";
11
12 public static function detect() {
13 return !empty($_SERVER["X-LSCACHE"]) || ( !empty($_SERVER["SERVER_SOFTWARE"]) && strtolower($_SERVER["SERVER_SOFTWARE"]) == "litespeed" );
14 }
15
16 public static function isCacheEnabled() {
17 return
18 !empty($_SERVER["X-LSCACHE"]) &&
19 in_array("on", array_map("trim", explode(",", $_SERVER["X-LSCACHE"]))) &&
20 !empty($_SERVER['LSCACHE_VARY_VALUE']) &&
21 in_array($_SERVER['LSCACHE_VARY_VALUE'], array("nitrodesktop", "nitrotablet", "nitromobile"));
22 }
23
24 public static function sendCacheHeader($maxAge = NULL) {
25 if (!$maxAge) {
26 nitropack_header("X-LiteSpeed-Cache-Control: public");
27 } else if (is_numeric($maxAge)) {
28 nitropack_header("X-LiteSpeed-Cache-Control: public,max-age=" . (int)$maxAge);
29 }
30 }
31
32 public static function purge($url = NULL, $tag = NULL) {
33 if ($url || $tag) {
34 $headerValues = [];
35
36 if ($url) {
37 $urlObj = new Url((new Url($url))->getNormalized());
38 if (!$urlObj->getQuery()) {
39 $headerValues[] = "uri=" . md5($urlObj->getPath());
40 } else {
41 $headerValues[] = "uri=" . md5($urlObj->getPath() . "?" . $urlObj->getQuery());
42 }
43 }
44
45 if ($tag) {
46 $headerValues[] = $tag;
47 }
48
49 nitropack_header("X-LiteSpeed-Purge: " . implode(", ", $headerValues), false);
50 } else {
51 nitropack_header("X-LiteSpeed-Purge: *", false);
52 }
53 }
54
55 public function init($stage) {
56 if (self::detect()) {
57 add_filter('nitropack_should_modify_htaccess', function() { return true; });
58 add_filter('nitropack_htaccess_rules', [$this, 'getHtaccessRules'], 10);
59
60 if (self::isCacheEnabled()) {
61 add_action('nitropack_integration_purge_url', [$this, 'purgeUrl']);
62 add_action('nitropack_integration_purge_all', [$this, 'purgeAll']);
63 add_action('nitropack_early_cache_headers', [$this, 'setupVary']);
64 add_action('nitropack_early_cache_headers', [$this, 'preventProxyCache']);
65 add_action('nitropack_cacheable_cache_headers', [$this, 'allowProxyCache']);
66 add_filter('nocache_headers', function($headers) {
67 $headers["X-LiteSpeed-Cache-Control"] = "no-cache";
68 return $headers;
69 });
70 } else {
71 add_filter('nitropack_needs_htaccess_changes', function() { return true; });
72 }
73 }
74 }
75
76 public function purgeUrl($url) {
77 self::purge($url);
78 }
79
80 public function purgeAll() {
81 self::purge();
82 }
83
84 public function setupVary() {
85 $cookies = []; // Configure vary based on NitroPack's variation cookies.
86
87 $nitro = get_nitropack()->getSdk();
88 if ($nitro && !empty($nitro->getConfig()->PageCache->SupportedCookies)) {
89 $cookies = $nitro->getConfig()->PageCache->SupportedCookies;
90 }
91
92 $device = new Device($_SERVER["HTTP_USER_AGENT"]);
93 $deviceStr = "nitrodesktop";
94
95 if ($device->isMobile()) {
96 $deviceStr = "nitromobile";
97 } else if ($device->isTablet()) {
98 $deviceStr = "nitrotablet";
99 }
100
101 $varyStr = "";
102
103 if ($cookies) {
104 $varyStr = implode(",", array_map(function($name) { return "cookie=$name"; }, $cookies)); // Vary on multiple cookies should look like this: cookie=name1,cookie=name2
105 }
106
107 $varyStr .= ($varyStr ? ", " : "") . "value=$deviceStr";
108
109 nitropack_header("X-LiteSpeed-Vary: $varyStr");
110 }
111
112 public function preventProxyCache() {
113 nitropack_header("X-LiteSpeed-Cache-Control: no-cache");
114 }
115
116 public function allowProxyCache() {
117 self::sendCacheHeader(3600);
118 $urlObj = new Url(NitroPack::getInstance()->getSdk()->getUrl());
119 if (!$urlObj->getQuery()) {
120 $uri = md5($urlObj->getPath());
121 } else {
122 $uri = md5($urlObj->getPath() . "?" . $urlObj->getQuery());
123 }
124
125 nitropack_header("X-LiteSpeed-Tag: uri=$uri");
126
127 // TODO: Add LSC-Cookie headers for variation cookies - https://docs.litespeedtech.com/lscache/devguide/controls/#lsc-cookie
128 }
129
130 public function getHtaccessRules($ruleLines) {
131 $rules = "
132 <IfModule LiteSpeed>
133 RewriteEngine on
134 CacheLookup on
135
136 RewriteRule .* - [E=Cache-Control:vary=nitrodesktop]
137
138 RewriteCond %{HTTP_USER_AGENT} Android|iPad|RIM\ Tablet|hp-tablet|Kindle\ Fire [NC]
139 RewriteRule .* - [E=Cache-Control:vary=nitrotablet]
140
141 RewriteCond %{HTTP_USER_AGENT} iPod|iPhone|MobileSafari|webOS|BlackBerry|windows\ phone|symbian|vodafone|opera\ mini|windows\ ce|smartphone|palm|midp [NC,OR]
142 RewriteCond %{HTTP_USER_AGENT} Android.*Mobile [NC,OR]
143 RewriteCond %{HTTP_USER_AGENT} Mobile.*Android [NC]
144 RewriteRule .* - [E=Cache-Control:vary=nitromobile]
145
146 # QSDROP
147
148 </IfModule>
149 ";
150
151 $nitro = get_nitropack()->getSdk();
152 if ($nitro && !empty($nitro->getConfig()->IgnoredParams)) {
153 $rules = str_replace("# QSDROP", implode("\n", array_map(function($param) { return "CacheKeyModify -qs:$param"; }, array_filter($nitro->getConfig()->IgnoredParams, function($param) { return $param != "ignorenitro"; }))), $rules);
154 }
155
156 return array_merge($ruleLines, explode("\n", $rules));
157 }
158 }
159