Current Path : /var/www/html/clients/amz.e-nk.ru/bitrix/modules/main/classes/general/ |
Current File : /var/www/html/clients/amz.e-nk.ru/bitrix/modules/main/classes/general/cache_html.php |
<? /*. require_module 'standard'; .*/ /*. require_module 'session'; .*/ /*. require_module 'zlib'; .*/ /*. require_module 'pcre'; .*/ class CHTMLPagesCache { /*. void .*/ function startCaching() { $HTML_PAGES_ROOT = $_SERVER["DOCUMENT_ROOT"].BX_PERSONAL_ROOT."/html_pages"; if( $_SERVER["REQUEST_METHOD"] === "POST" || array_key_exists(session_name(), $_COOKIE) || array_key_exists(session_name(), $_REQUEST) || (strncmp($_SERVER["REQUEST_URI"], BX_ROOT, strlen(BX_ROOT)) == 0) || (strncmp($_SERVER["REQUEST_URI"], BX_PERSONAL_ROOT, strlen(BX_ROOT)) == 0) || (preg_match("#^/index_controller\\.php#", $_SERVER["REQUEST_URI"]) > 0) ) { return; } $arHTMLPagesOptions = array(); if(file_exists($HTML_PAGES_ROOT."/.config.php")) include($HTML_PAGES_ROOT."/.config.php"); //Check for stored authorization if( isset($arHTMLPagesOptions["STORE_PASSWORD"]) && $arHTMLPagesOptions["STORE_PASSWORD"] == "Y" && isset($_COOKIE[$arHTMLPagesOptions["COOKIE_LOGIN"]]) && $_COOKIE[$arHTMLPagesOptions["COOKIE_LOGIN"]] <> '' && isset($_COOKIE[$arHTMLPagesOptions["COOKIE_PASS"]]) && $_COOKIE[$arHTMLPagesOptions["COOKIE_PASS"]] <> '' ) { return; } //Check for masks $p = strpos($_SERVER["REQUEST_URI"], "?"); if($p === false) $PAGES_FILE = $_SERVER["REQUEST_URI"]; else $PAGES_FILE = substr($_SERVER["REQUEST_URI"], 0, $p); if(is_array($arHTMLPagesOptions["~EXCLUDE_MASK"])) { foreach($arHTMLPagesOptions["~EXCLUDE_MASK"] as $mask) { if(preg_match($mask, $PAGES_FILE) > 0) { return; } } } if(is_array($arHTMLPagesOptions["~INCLUDE_MASK"])) { foreach($arHTMLPagesOptions["~INCLUDE_MASK"] as $mask) { if(preg_match($mask, $PAGES_FILE) > 0) { $PAGES_FILE = "*"; break; } } } if($PAGES_FILE !== "*") return; $arMatch = array(); if(preg_match("#^(/.+?)\\.php\\?(.*)#", $_SERVER["REQUEST_URI"], $arMatch) > 0) { if(strpos($arMatch[2], "\\")!==false || strpos($arMatch[2], "/")!==false) return; $PAGES_FILE = $HTML_PAGES_ROOT.$arMatch[1]."@".$arMatch[2].".html"; } elseif(preg_match("#^(/.+)\\.php$#", $_SERVER["REQUEST_URI"], $arMatch) > 0) { $PAGES_FILE = $HTML_PAGES_ROOT.$arMatch[1]."@.html"; } if(preg_match("#^(.*?)/\\?(.*)#", $_SERVER["REQUEST_URI"], $arMatch) > 0) { if(strpos($arMatch[2], "\\")!==false || strpos($arMatch[2], "/")!==false) return; if(strlen($arMatch[1]) && substr($arMatch[1], 0, 1)!=="/") return; $PAGES_FILE = $HTML_PAGES_ROOT.$arMatch[1]."/index@".$arMatch[2].".html"; } elseif(preg_match("#^(.*)/$#", $_SERVER["REQUEST_URI"], $arMatch) > 0) { if(strlen($arMatch[1]) && substr($arMatch[1], 0, 1)!=="/") return; $PAGES_FILE = $HTML_PAGES_ROOT.$arMatch[1]."/index@.html"; } //This checks for invalid symbols //TODO: make it Windows compatible if(preg_match("/(\\?|\\*|\\.\\.)/", $PAGES_FILE) > 0) return; if(file_exists($PAGES_FILE)) { //Update statistic CHTMLPagesCache::writeStatistic(1); $mtime = filemtime($PAGES_FILE); $fsize = filesize($PAGES_FILE); //Handle ETag $ETag = md5($PAGES_FILE.$fsize.$mtime); if(array_key_exists("HTTP_IF_NONE_MATCH", $_SERVER) && ($_SERVER['HTTP_IF_NONE_MATCH'] === $ETag)) { CHTMLPagesCache::SetStatus("304 Not Modified"); die(); } header("ETag: ".$ETag); //Handle Last Modified $lastModified = gmdate('D, d M Y H:i:s', $mtime).' GMT'; if(array_key_exists("HTTP_IF_MODIFIED_SINCE", $_SERVER) && ($_SERVER['HTTP_IF_MODIFIED_SINCE'] === $lastModified)) { CHTMLPagesCache::SetStatus("304 Not Modified"); die(); } header("Expires: Fri, 7 Jun 1974 04:00:00 GMT"); header('Last-Modified: '.$lastModified); $fp = fopen($PAGES_FILE, "rb"); if($fp !== false) { if(version_compare(phpversion(), "5.3.0", "<") && (($v = ini_get("magic_quotes_runtime")) == 1 || strtolower($v) == 'on')) set_magic_quotes_runtime(0); $contents = fread($fp, $fsize); fclose($fp); //Try to parse charset encoding $head_end = strpos($contents, "</head>"); if($head_end !== false) { if(preg_match("#<meta\\s+http-equiv\\s*=\\s*(['\"])Content-Type(\\1)\\s+content\\s*=\\s*(['\"])(.*?)(\\3)#im", substr($contents, 0, $head_end), $arMatch)) { header("Content-type: ".$arMatch[4]); } } //compression support $compress = ""; if($arHTMLPagesOptions["COMPRESS"]) { if(isset($_SERVER["HTTP_ACCEPT_ENCODING"])) { if(strpos($_SERVER["HTTP_ACCEPT_ENCODING"],'x-gzip') !== false) $compress = "x-gzip"; elseif(strpos($_SERVER["HTTP_ACCEPT_ENCODING"],'gzip') !== false) $compress = "gzip"; } } if($compress) { if(isset($_SERVER["HTTP_USER_AGENT"])) { $USER_AGENT = $_SERVER["HTTP_USER_AGENT"]; if((strpos($USER_AGENT, "MSIE 5")>0 || strpos($USER_AGENT, "MSIE 6.0")>0) && strpos($USER_AGENT, "Opera")===false) $contents = str_repeat(" ", 2048)."\r\n".$contents; } $Size = function_exists("mb_strlen")? mb_strlen($contents, 'latin1'): strlen($contents); $Crc = crc32($contents); $contents = gzcompress($contents, 4); $contents = function_exists("mb_substr")? mb_substr($contents, 0, -4, 'latin1'): substr($contents, 0, -4); header("Content-Encoding: $compress"); echo "\x1f\x8b\x08\x00\x00\x00\x00\x00",$contents,pack('V',$Crc),pack('V',$Size); } else { header("Content-Length: ".filesize($PAGES_FILE)); echo $contents; } die(); } } else//if(file_exists($PAGES_FILE)) { define('HTML_PAGES_FILE', $PAGES_FILE); } } //Deletes all above html_pages /*. float .*/ function deleteRecursive(/*. string .*/$path = "") { $base_bir = $_SERVER["DOCUMENT_ROOT"].BX_PERSONAL_ROOT."/html_pages"; //Estimate for freed space $bytes = 0.0; //Check if someone is trieng to escape from $base_dir if(strpos($path, "..")!==false) return 0; $dh = false; if(is_dir($base_bir.$path)) $dh = opendir($base_bir.$path); if($dh !== false) { while(($file = readdir($dh)) !== false) { if( $file === "." || $file === ".." || $file === "404.php" || $file === ".htaccess" || $file === ".config.php" || $file === ".enabled" ) continue; $file_path = $base_bir.$path."/".$file; if(is_dir($file_path)) { $bytes += CHTMLPagesCache::deleteRecursive($path.$file."/"); rmdir($file_path); } elseif(is_file($file_path)) { $bytes += filesize($file_path); unlink($file_path); } } closedir($dh); } return doubleval($bytes); } function OnEpilog() { global $USER; $bAutorized = is_object($USER) && $USER->IsAuthorized(); if(!$bAutorized && defined("HTML_PAGES_FILE")) { @setcookie(session_name(), "", time()-360000, "/"); } $bExcludeByFile = $_SERVER["SCRIPT_NAME"] == "/bitrix/admin/get_start_menu.php"; $posts = 0; $bytes = 0.0; $all_clean = false; //Check if modifyng action happend if(($_SERVER["REQUEST_METHOD"] === "POST") || ($bAutorized && check_bitrix_sessid() && !$bExcludeByFile)) { //if it was admin post if(strncmp($_SERVER["REQUEST_URI"], "/bitrix/", 8) === 0) { //Then will clean all the cache $bytes = CHTMLPagesCache::deleteRecursive("/"); $all_clean = true; } //check if it was SEF post elseif(array_key_exists("SEF_APPLICATION_CUR_PAGE_URL", $_REQUEST) && file_exists($_SERVER['DOCUMENT_ROOT']."/urlrewrite.php")) { $arUrlRewrite = array(); include($_SERVER['DOCUMENT_ROOT']."/urlrewrite.php"); foreach($arUrlRewrite as $val) { if(preg_match($val["CONDITION"], $_SERVER["REQUEST_URI"]) > 0) { if (strlen($val["RULE"]) > 0) $url = preg_replace($val["CONDITION"], (StrLen($val["PATH"]) > 0 ? $val["PATH"]."?" : "").$val["RULE"], $_SERVER["REQUEST_URI"]); else $url = $val["PATH"]; $pos=strpos($url, "?"); if($pos !== false) { $url = substr($url, 0, $pos); } $url = substr($url, 0, strrpos($url, "/")+1); $bytes = CHTMLPagesCache::deleteRecursive($url); break; } } } //public page post else { $folder = substr($_SERVER["REQUEST_URI"], 0, strrpos($_SERVER["REQUEST_URI"], "/")); $bytes = CHTMLPagesCache::deleteRecursive($folder); } $posts++; } if($bytes > 0.0 && class_exists("cdiskquota")) { CDiskQuota::updateDiskQuota("file", $bytes, "delete"); } if($posts || $bytes) { CHTMLPagesCache::writeStatistic( 0, //hit 0, //miss 0, //quota $posts, //posts ($all_clean? false: -$bytes) //files ); } } function CleanAll() { $bytes = CHTMLPagesCache::deleteRecursive("/"); if($bytes > 0.0 && class_exists("cdiskquota")) { CDiskQuota::updateDiskQuota("file", $bytes, "delete"); } } function writeFile($file_name, $content) { global $USER; if(is_object($USER) && $USER->IsAuthorized()) return; $content_len = function_exists('mb_strlen')? mb_strlen($content, 'latin1'): strlen($content); if($content_len <= 0) return; $arHTMLPagesOptions = CHTMLPagesCache::GetOptions(true); if(!is_array($arHTMLPagesOptions)) return; //Let's be pessimists $bQuota = false; if(class_exists("cdiskquota")) { $quota = new CDiskQuota(); if($quota->checkDiskQuota(array("FILE_SIZE" => $content_len))) $bQuota = true; } else { $bQuota = true; } $arStat = CHTMLPagesCache::readStatistic(); if($arStat) $cached_size = $arStat["FILE_SIZE"]; else $cached_size = 0.0; $cache_quota = doubleval($arHTMLPagesOptions["~FILE_QUOTA"]); if($bQuota && ($cache_quota > 0.0)) { if($cache_quota < ($cached_size + $content_len)) $bQuota = false; } if($bQuota) { CheckDirPath($file_name); $written = 0; $tmp_filename = $file_name.md5(mt_rand()).".tmp"; $file = fopen($tmp_filename, "wb"); if($file !== false) { $written = fwrite($file, $content); if($written == $content_len) { fclose($file); if(file_exists($file_name)) unlink($file_name); rename($tmp_filename, $file_name); @chmod($file_name, defined("BX_FILE_PERMISSIONS")? BX_FILE_PERMISSIONS: 0664); if(class_exists("cdiskquota")) { CDiskQuota::updateDiskQuota("file", $content_len, "copy"); } } else { $written = 0; fclose($file); if(file_exists($file_name)) unlink($file_name); if(file_exists($tmp_filename)) unlink($tmp_filename); } } $arStat = CHTMLPagesCache::writeStatistic( 0, //hit 1, //miss 0, //quota 0, //posts $written //files ); } else { //Fire cleanup CHTMLPagesCache::CleanAll(); CHTMLPagesCache::writeStatistic(0, 0, 1, 0, false); } } function IsOn() { return file_exists($_SERVER["DOCUMENT_ROOT"].BX_PERSONAL_ROOT."/html_pages/.enabled"); } function SetEnabled($status) { $file_name = $_SERVER["DOCUMENT_ROOT"].BX_PERSONAL_ROOT."/html_pages/.enabled"; if($status) { RegisterModuleDependences("main", "OnEpilog", "main", "CHTMLPagesCache", "OnEpilog"); RegisterModuleDependences("main", "OnLocalRedirect", "main", "CHTMLPagesCache", "OnEpilog"); //For very first run we have to fall into defaults CHTMLPagesCache::SetOptions(CHTMLPagesCache::GetOptions()); if(!file_exists($file_name)) { $f = fopen($file_name, "w"); fwrite($f, "0,0,0,0,0"); fclose($f); @chmod($file_name, defined("BX_FILE_PERMISSIONS")? BX_FILE_PERMISSIONS: 0664); } } else { UnRegisterModuleDependences("main", "OnEpilog", "main", "CHTMLPagesCache", "OnEpilog"); UnRegisterModuleDependences("main", "OnLocalRedirect", "main", "CHTMLPagesCache", "OnEpilog"); if(file_exists($file_name)) unlink($file_name); } } function SetOptions($arOptions = array(), $bCompile = true) { if($bCompile) CHTMLPagesCache::CompileOptions($arOptions); $file_name = $_SERVER["DOCUMENT_ROOT"].BX_PERSONAL_ROOT."/html_pages/.config.php"; $tmp_filename = $file_name.md5(mt_rand()).".tmp"; CheckDirPath($file_name); $fh = fopen($tmp_filename, "wb"); if($fh !== false) { $content = "<?\n\$arHTMLPagesOptions = array(\n"; foreach($arOptions as $key => $value) { if(is_array($value)) { $content .= "\t\"".EscapePHPString($key)."\" => array(\n"; foreach($value as $key2 => $val) { $content .= "\t\t\"".EscapePHPString($key2)."\" => \"".EscapePHPString($val)."\",\n"; } $content .= "\t),\n"; } else { $content .= "\t\"".EscapePHPString($key)."\" => \"".EscapePHPString($value)."\",\n"; } } $content .= ");\n?>\n"; $written = fwrite($fh, $content); $len = function_exists('mb_strlen')? mb_strlen($content, 'latin1'): strlen($content); if($written === $len) { fclose($fh); if(file_exists($file_name)) unlink($file_name); rename($tmp_filename, $file_name); @chmod($file_name, defined("BX_FILE_PERMISSIONS")? BX_FILE_PERMISSIONS: 0664); } else { fclose($fh); if(file_exists($tmp_filename)) unlink($tmp_filename); } } } function GetOptions($bCheck = false) { $arHTMLPagesOptions = array(); $file_name = $_SERVER["DOCUMENT_ROOT"].BX_PERSONAL_ROOT."/html_pages/.config.php"; if(file_exists($file_name)) { include($file_name); } if(!is_array($arHTMLPagesOptions)) { if($bCheck) return false; else $arHTMLPagesOptions = array(); } $bCompile = false; if(!array_key_exists("INCLUDE_MASK", $arHTMLPagesOptions)) { $arHTMLPagesOptions["INCLUDE_MASK"] = "*.php;*/"; $bCompile = true; } if(!array_key_exists("EXCLUDE_MASK", $arHTMLPagesOptions)) { $arHTMLPagesOptions["EXCLUDE_MASK"] = "/bitrix/*;/404.php"; $bCompile = true; } if(!array_key_exists("FILE_QUOTA", $arHTMLPagesOptions)) { $arHTMLPagesOptions["FILE_QUOTA"] = 100; $bCompile = true; } if($bCompile) { CHTMLPagesCache::CompileOptions($arHTMLPagesOptions); } return $arHTMLPagesOptions; } function CompileOptions(&$arOptions) { $arOptions["~INCLUDE_MASK"] = array(); $inc = str_replace( array("\\", ".", "?", "*", "'"), array("/", "\.", ".", ".*?", "\'"), $arOptions["INCLUDE_MASK"] ); $arIncTmp = explode(";", $inc); foreach($arIncTmp as $mask) { $mask = trim($mask); if(strlen($mask) > 0) $arOptions["~INCLUDE_MASK"][] = "'^".$mask."$'"; } $arOptions["~EXCLUDE_MASK"] = array(); $inc = str_replace( array("\\", ".", "?", "*", "'"), array("/", "\.", ".", ".*?", "\'"), $arOptions["EXCLUDE_MASK"] ); $arIncTmp = explode(";", $inc); foreach($arIncTmp as $mask) { $mask = trim($mask); if(strlen($mask) > 0) $arOptions["~EXCLUDE_MASK"][] = "'^".$mask."$'"; } if(intval($arOptions["FILE_QUOTA"]) > 0) $arOptions["~FILE_QUOTA"] = doubleval($arOptions["FILE_QUOTA"]) * 1024.0 * 1024.0; else $arOptions["~FILE_QUOTA"] = 0.0; $arOptions["COMPRESS"] = IsModuleInstalled('compression'); $arOptions["STORE_PASSWORD"] = COption::GetOptionString("main", "store_password", "Y"); $cookie_prefix = COption::GetOptionString('main', 'cookie_name', 'BITRIX_SM'); $arOptions["COOKIE_LOGIN"] = $cookie_prefix.'_LOGIN'; $arOptions["COOKIE_PASS"] = $cookie_prefix.'_UIDH'; } function readStatistic() { $arResult = false; $file_name = $_SERVER["DOCUMENT_ROOT"].BX_PERSONAL_ROOT."/html_pages/.enabled"; if(file_exists($file_name)) { $fp = fopen($file_name, "r"); if($fp !== false) { $file_values = explode(",", fgets($fp)); fclose($fp); $arResult = array( "HITS" => intval($file_values[0]), "MISSES" => intval($file_values[1]), "QUOTA" => intval($file_values[2]), "POSTS" => intval($file_values[3]), "FILE_SIZE" => doubleval($file_values[4]), ); } } return $arResult; } function writeStatistic($hit = 0, $miss = 0, $quota = 0, $posts = 0, $files = 0.0) { $file_name = $_SERVER["DOCUMENT_ROOT"].BX_PERSONAL_ROOT."/html_pages/.enabled"; $fp = @fopen($file_name, "r+"); if($fp) $file_values = explode(",", fgets($fp)); else $file_values = array(); if(count($file_values) > 1) { $new_file_values = array( intval($file_values[0]) + $hit, intval($file_values[1]) + $miss, intval($file_values[2]) + $quota, intval($file_values[3]) + $posts, $files === false? 0: doubleval($file_values[4]) + doubleval($files), ); fseek($fp, 0); ftruncate($fp, 0); fwrite($fp, implode(",", $new_file_values)); } if($fp) fclose($fp); } function SetStatus($status) { $bCgi = (stristr(php_sapi_name(), "cgi") !== false); $bFastCgi = ($bCgi && (array_key_exists('FCGI_ROLE', $_SERVER) || array_key_exists('FCGI_ROLE', $_ENV))); if($bCgi && !$bFastCgi) header("Status: ".$status); else header($_SERVER["SERVER_PROTOCOL"]." ".$status); } } ?>