PluginProbe ʕ •ᴥ•ʔ
LiteSpeed Cache / 7.8.1
LiteSpeed Cache v7.8.1
trunk 1.0.15 1.9.1.1 2.9.9.2 3.6.4 4.6 5.7.0.1 6.5.4 7.0.0.1 7.0.1 7.1 7.2 7.3 7.3.0.1 7.4 7.5 7.5.0.1 7.6 7.6.1 7.6.2 7.7 7.8 7.8.0.1 7.8.1
litespeed-cache / src / rest.cls.php
litespeed-cache / src Last commit date
cdn 2 months ago data_structure 2 months ago activation.cls.php 2 months ago admin-display.cls.php 2 months ago admin-settings.cls.php 2 months ago admin.cls.php 2 months ago api.cls.php 2 months ago avatar.cls.php 2 months ago base.cls.php 2 months ago cdn.cls.php 2 months ago cloud-auth-callback.trait.php 2 months ago cloud-auth-ip.trait.php 2 months ago cloud-auth.trait.php 2 months ago cloud-misc.trait.php 2 months ago cloud-node.trait.php 2 months ago cloud-request.trait.php 2 months ago cloud.cls.php 2 months ago conf.cls.php 2 months ago control.cls.php 2 months ago core.cls.php 2 months ago crawler-map.cls.php 2 months ago crawler.cls.php 2 months ago css.cls.php 2 months ago data.cls.php 2 months ago data.upgrade.func.php 2 months ago db-optm.cls.php 2 months ago debug2.cls.php 2 months ago doc.cls.php 2 months ago error.cls.php 2 months ago esi.cls.php 2 months ago file.cls.php 2 months ago guest.cls.php 2 months ago gui.cls.php 2 months ago health.cls.php 2 months ago htaccess.cls.php 2 months ago img-optm-manage.trait.php 2 months ago img-optm-pull.trait.php 2 months ago img-optm-send.trait.php 2 months ago img-optm.cls.php 2 months ago import.cls.php 2 months ago import.preset.cls.php 2 months ago lang.cls.php 2 months ago localization.cls.php 2 months ago media.cls.php 2 months ago metabox.cls.php 2 months ago object-cache-wp.cls.php 2 months ago object-cache.cls.php 2 months ago object.lib.php 2 months ago optimize.cls.php 2 months ago optimizer.cls.php 2 months ago placeholder.cls.php 2 months ago purge.cls.php 2 months ago report.cls.php 2 months ago rest.cls.php 2 months ago root.cls.php 2 months ago router.cls.php 2 months ago str.cls.php 2 months ago tag.cls.php 2 months ago task.cls.php 2 months ago tool.cls.php 2 months ago ucss.cls.php 2 months ago utility.cls.php 2 months ago vary.cls.php 2 months ago vpi.cls.php 2 months ago
rest.cls.php
387 lines
1 <?php
2 /**
3 * REST endpoints and helpers for LiteSpeed.
4 *
5 * @since 2.9.4
6 * @package LiteSpeed
7 */
8
9 namespace LiteSpeed;
10
11 defined( 'WPINC' ) || exit();
12
13 /**
14 * Class REST
15 *
16 * Registers plugin REST endpoints and exposes helpers for REST detection.
17 */
18 class REST extends Root {
19
20 const LOG_TAG = '☎️';
21
22 /**
23 * Whether current request is an internal REST call.
24 *
25 * @var bool
26 */
27 private $_internal_rest_status = false;
28
29 /**
30 * Constructor.
31 *
32 * @since 2.9.4
33 */
34 public function __construct() {
35 // Hook to internal REST call.
36 add_filter( 'rest_request_before_callbacks', [ $this, 'set_internal_rest_on' ] );
37 add_filter( 'rest_request_after_callbacks', [ $this, 'set_internal_rest_off' ] );
38
39 add_action( 'rest_api_init', [ $this, 'rest_api_init' ] );
40 }
41
42 /**
43 * Register REST routes.
44 *
45 * @since 3.0
46 * @return void
47 */
48 public function rest_api_init() {
49 // Activate or deactivate a specific crawler callback
50 register_rest_route( 'litespeed/v1', '/toggle_crawler_state', [
51 'methods' => 'POST',
52 'callback' => [ $this, 'toggle_crawler_state' ],
53 'permission_callback' => function () {
54 return current_user_can( 'manage_network_options' ) || current_user_can( 'manage_options' );
55 },
56 ] );
57
58 register_rest_route( 'litespeed/v1', '/tool/check_ip', [
59 'methods' => 'GET',
60 'callback' => [ $this, 'check_ip' ],
61 'permission_callback' => function () {
62 return current_user_can( 'manage_network_options' ) || current_user_can( 'manage_options' );
63 },
64 ] );
65
66 register_rest_route( 'litespeed/v1', '/guest/sync', [
67 'methods' => 'GET',
68 'callback' => [ $this, 'guest_sync' ],
69 'permission_callback' => function () {
70 return current_user_can( 'manage_network_options' ) || current_user_can( 'manage_options' );
71 },
72 ] );
73
74 // IP callback validate
75 register_rest_route( 'litespeed/v3', '/ip_validate', [
76 'methods' => 'POST',
77 'callback' => [ $this, 'ip_validate' ],
78 'permission_callback' => [ $this, 'is_from_cloud' ],
79 ] );
80
81 // 1.2. WP REST Dryrun Callback
82 register_rest_route( 'litespeed/v3', '/wp_rest_echo', [
83 'methods' => 'POST',
84 'callback' => [ $this, 'wp_rest_echo' ],
85 'permission_callback' => [ $this, 'is_from_cloud' ],
86 ] );
87 register_rest_route( 'litespeed/v3', '/ping', [
88 'methods' => 'POST',
89 'callback' => [ $this, 'ping' ],
90 'permission_callback' => [ $this, 'is_from_cloud' ],
91 ] );
92
93 // CDN setup callback notification
94 register_rest_route( 'litespeed/v3', '/cdn_status', [
95 'methods' => 'POST',
96 'callback' => [ $this, 'cdn_status' ],
97 'permission_callback' => [ $this, 'is_from_cloud' ],
98 ] );
99
100 // Image optm notify_img
101 // Need validation
102 register_rest_route( 'litespeed/v1', '/notify_img', [
103 'methods' => 'POST',
104 'callback' => [ $this, 'notify_img' ],
105 'permission_callback' => [ $this, 'is_from_cloud' ],
106 ] );
107
108 register_rest_route( 'litespeed/v1', '/notify_ccss', [
109 'methods' => 'POST',
110 'callback' => [ $this, 'notify_ccss' ],
111 'permission_callback' => [ $this, 'is_from_cloud' ],
112 ] );
113
114 register_rest_route( 'litespeed/v1', '/notify_ucss', [
115 'methods' => 'POST',
116 'callback' => [ $this, 'notify_ucss' ],
117 'permission_callback' => [ $this, 'is_from_cloud' ],
118 ] );
119
120 register_rest_route( 'litespeed/v1', '/notify_vpi', [
121 'methods' => 'POST',
122 'callback' => [ $this, 'notify_vpi' ],
123 'permission_callback' => [ $this, 'is_from_cloud' ],
124 ] );
125
126 register_rest_route( 'litespeed/v3', '/err_domains', [
127 'methods' => 'POST',
128 'callback' => [ $this, 'err_domains' ],
129 'permission_callback' => [ $this, 'is_from_cloud' ],
130 ] );
131
132 // Image optm check_img
133 // Need validation
134 register_rest_route( 'litespeed/v1', '/check_img', [
135 'methods' => 'POST',
136 'callback' => [ $this, 'check_img' ],
137 'permission_callback' => [ $this, 'is_from_cloud' ],
138 ] );
139 }
140
141 /**
142 * Call to freeze or melt the crawler clicked
143 *
144 * @since 4.3
145 */
146 public function toggle_crawler_state() {
147 // phpcs:ignore WordPress.Security.NonceVerification.Missing -- REST API nonce verified by WordPress
148 $crawler_id = isset( $_POST['crawler_id'] ) ? sanitize_text_field( wp_unslash( $_POST['crawler_id'] ) ) : '';
149
150 if ( '' !== $crawler_id ) {
151 return $this->cls( 'Crawler' )->toggle_activeness( $crawler_id ) ? 1 : 0;
152 }
153 }
154
155 /**
156 * Check if the request is from cloud nodes.
157 *
158 * @since 4.2
159 * @since 4.4.7 Token/API key validation makes IP validation redundant.
160 * @return bool
161 */
162 public function is_from_cloud() {
163 return $this->cls( 'Cloud' )->is_from_cloud();
164 }
165
166 /**
167 * Ping pong.
168 *
169 * @since 3.0.4
170 * @return mixed
171 */
172 public function ping() {
173 return $this->cls( 'Cloud' )->ping();
174 }
175
176 /**
177 * Launch IP check.
178 *
179 * @since 3.0
180 * @return mixed
181 */
182 public function check_ip() {
183 return Tool::cls()->check_ip();
184 }
185
186 /**
187 * Sync Guest Mode IP/UA lists.
188 *
189 * @since 7.7
190 * @return array
191 */
192 public function guest_sync() {
193 return Guest::cls()->sync_lists();
194 }
195
196 /**
197 * Validate IPs from cloud.
198 *
199 * @since 3.0
200 * @return mixed
201 */
202 public function ip_validate() {
203 return $this->cls( 'Cloud' )->ip_validate();
204 }
205
206 /**
207 * REST echo helper.
208 *
209 * @since 3.0
210 * @return mixed
211 */
212 public function wp_rest_echo() {
213 return $this->cls( 'Cloud' )->wp_rest_echo();
214 }
215
216 /**
217 * Endpoint to notify plugin of CDN status updates.
218 *
219 * @since 7.0
220 * @return mixed
221 */
222 public function cdn_status() {
223 return $this->cls( 'Cloud' )->update_cdn_status();
224 }
225
226 /**
227 * Image optimization notification.
228 *
229 * @since 3.0
230 * @return mixed
231 */
232 public function notify_img() {
233 return Img_Optm::cls()->notify_img();
234 }
235
236 /**
237 * Critical CSS notification.
238 *
239 * @since 7.1
240 * @return mixed
241 */
242 public function notify_ccss() {
243 self::debug( 'notify_ccss' );
244 return CSS::cls()->notify();
245 }
246
247 /**
248 * Unique CSS notification.
249 *
250 * @since 5.2
251 * @return mixed
252 */
253 public function notify_ucss() {
254 self::debug( 'notify_ucss' );
255 return UCSS::cls()->notify();
256 }
257
258 /**
259 * Viewport Images notification.
260 *
261 * @since 4.7
262 * @return mixed
263 */
264 public function notify_vpi() {
265 self::debug( 'notify_vpi' );
266 return VPI::cls()->notify();
267 }
268
269 /**
270 * Error domain report from cloud.
271 *
272 * @since 4.7
273 * @return mixed
274 */
275 public function err_domains() {
276 self::debug( 'err_domains' );
277 return $this->cls( 'Cloud' )->rest_err_domains();
278 }
279
280 /**
281 * Launch image check.
282 *
283 * @since 3.0
284 * @return mixed
285 */
286 public function check_img() {
287 return Img_Optm::cls()->check_img();
288 }
289
290 /**
291 * Return a standardized error payload.
292 *
293 * @since 5.7.0.1
294 * @param string|int $code Error code.
295 * @return array
296 */
297 public static function err( $code ) {
298 return [
299 '_res' => 'err',
300 '_msg' => $code,
301 ];
302 }
303
304 /**
305 * Set internal REST tag to ON.
306 *
307 * @since 2.9.4
308 * @param mixed $not_used Passthrough value from the filter.
309 * @return mixed
310 */
311 public function set_internal_rest_on( $not_used = null ) {
312 $this->_internal_rest_status = true;
313 Debug2::debug2( '[REST] �
314 Internal REST ON [filter] rest_request_before_callbacks' );
315
316 return $not_used;
317 }
318
319 /**
320 * Set internal REST tag to OFF.
321 *
322 * @since 2.9.4
323 * @param mixed $not_used Passthrough value from the filter.
324 * @return mixed
325 */
326 public function set_internal_rest_off( $not_used = null ) {
327 $this->_internal_rest_status = false;
328 Debug2::debug2( '[REST] Internal REST OFF [filter] rest_request_after_callbacks' );
329
330 return $not_used;
331 }
332
333 /**
334 * Whether current request is an internal REST call.
335 *
336 * @since 2.9.4
337 * @return bool
338 */
339 public function is_internal_rest() {
340 return $this->_internal_rest_status;
341 }
342
343 /**
344 * Check whether a URL or current page is a REST request.
345 *
346 * @since 2.9.3
347 * @since 2.9.4 Moved here from Utility, dropped static.
348 * @param string|false $url URL to check; when false checks current request.
349 * @return bool
350 */
351 public function is_rest( $url = false ) {
352 // For WP 4.4.0- compatibility.
353 if ( ! function_exists( 'rest_get_url_prefix' ) ) {
354 return ( defined( 'REST_REQUEST' ) && REST_REQUEST );
355 }
356
357 $prefix = rest_get_url_prefix();
358
359 // Case #1: After WP_REST_Request initialization.
360 if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
361 return true;
362 }
363
364 // Case #2: Support "plain" permalink settings.
365 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
366 $route = isset( $_GET['rest_route'] ) ? sanitize_text_field( wp_unslash( $_GET['rest_route'] ) ) : '';
367
368 if ( $route && 0 === strpos( trim( $route, '\\/' ), $prefix, 0 ) ) {
369 return true;
370 }
371
372 if ( !$url ) {
373 return false;
374 }
375
376 // Case #3: URL path begins with wp-json/ (REST prefix) – safe for subfolder installs.
377 $rest_url = wp_parse_url( site_url( $prefix ) );
378 $current_url = wp_parse_url( $url );
379
380 if ( false !== $current_url && ! empty( $current_url['path'] ) && false !== $rest_url && ! empty( $rest_url['path'] ) ) {
381 return 0 === strpos( $current_url['path'], $rest_url['path'] );
382 }
383
384 return false;
385 }
386 }
387