%PDF- %PDF-
Direktori : /proc/self/root/home/bitrix/www/bitrix/modules/bitrixcloud/classes/general/ |
Current File : //proc/self/root/home/bitrix/www/bitrix/modules/bitrixcloud/classes/general/cdn.php |
<?php IncludeModuleLangFile(__FILE__); class CBitrixCloudCDN { /** * * @var CBitrixCloudCDNConfig $config * */ private static $config = /*.(CBitrixCloudCDNConfig).*/ null; private static $proto = ""; private static $ajax = false; private static $domain_changed = false; /** * * @return bool * */ public static function IsActive() { foreach (GetModuleEvents("main", "OnEndBufferContent", true) as $arEvent) { if ($arEvent["TO_MODULE_ID"] === "bitrixcloud" && $arEvent["TO_CLASS"] === "CBitrixCloudCDN") { return true; } } return false; } /** * * @return void * @throws CBitrixCloudException */ private static function stop() { $o = CBitrixCloudCDNConfig::getInstance()->loadFromOptions(); $a = new CBitrixCloudCDNWebService($o->getDomain()); $a->actionStop(); } /** * * @param bool $bActive * @param bool $force * @return bool * */ public static function SetActive($bActive, $force = false) { /* @global CMain $APPLICATION */ global $APPLICATION; if ($bActive) { if (!self::IsActive() || $force) { try { $o = CBitrixCloudCDNConfig::getInstance()->loadRemoteXML(true); $o->saveToOptions(); if (!$o->isActive()) { if ( $o->getQuota()->getTrafficSize() > $o->getQuota()->getAllowedSize() ) { $ex = new CApplicationException(GetMessage("BCL_CDN_ERROR_QUOTA_LIMIT")); $APPLICATION->ThrowException($ex); return false; } elseif ( $o->getQuota()->isExpired() ) { $ex = new CApplicationException(GetMessage("BCL_CDN_ERROR_QUOTA_EXPIRED")); $APPLICATION->ThrowException($ex); return false; } } RegisterModuleDependences("main", "OnEndBufferContent", "bitrixcloud", "CBitrixCloudCDN", "OnEndBufferContent"); self::$domain_changed = false; } catch(CBitrixCloudException $e) { $ex = new CApplicationException($e->getMessage()."\n".$e->getDebugInfo()); $APPLICATION->ThrowException($ex); return false; } } elseif (self::$domain_changed) { try { $o = CBitrixCloudCDNConfig::getInstance()->loadRemoteXML(true); $o->saveToOptions(); self::$domain_changed = false; } catch(CBitrixCloudException $e) { $ex = new CApplicationException($e->getMessage()."\n".$e->getDebugInfo()); $APPLICATION->ThrowException($ex); return false; } } } else { if (self::IsActive() || $force) { try { self::stop(); UnRegisterModuleDependences("main", "OnEndBufferContent", "bitrixcloud", "CBitrixCloudCDN", "OnEndBufferContent"); } catch(CBitrixCloudException $e) { UnRegisterModuleDependences("main", "OnEndBufferContent", "bitrixcloud", "CBitrixCloudCDN", "OnEndBufferContent"); $ex = new CApplicationException($e->getMessage()."\n".$e->getDebugInfo()); $APPLICATION->ThrowException($ex); return false; } } } return true; } /** * * @return bool * */ private static function updateConfig() { if (!self::$config->lock()) return true; $delayExpiration = true; try { try { self::$config = CBitrixCloudCDNConfig::getInstance()->loadRemoteXML(); self::$config->saveToOptions(); self::$config->unlock(); } catch(CBitrixCloudException $e) { //In case of documented XML error we'll disable CDN if($e->getErrorCode() !== "") { self::SetActive(false); $delayExpiration = false; } throw $e; } } catch (Exception $e) { if ($delayExpiration) { self::$config->setExpired(time() + 1800); } CAdminNotify::Add(array( "MESSAGE" => GetMessage("BCL_CDN_NOTIFY", array( "#HREF#" => "/bitrix/admin/bitrixcloud_cdn.php?lang=".LANGUAGE_ID, )), "TAG" => "bitrixcloud_off", "MODULE_ID" => "bitrixcloud", "ENABLE_CLOSE" => "Y", )); self::$config->unlock(); return false; } self::$config->unlock(); //Web service were disabled if (!self::$config->isActive()) { //By traffic quota if ( self::$config->getQuota()->getTrafficSize() > self::$config->getQuota()->getAllowedSize() ) { self::$config->setExpired(time() + 1800); CAdminNotify::Add(array( "MESSAGE" => GetMessage("BCL_CDN_NOTIFY_QUOTA_LIMIT"), "TAG" => "bitrixcloud_off", "MODULE_ID" => "bitrixcloud", "ENABLE_CLOSE" => "N", )); self::$config->unlock(); return false; } //Or by license elseif ( self::$config->getQuota()->isExpired() ) { self::$config->setExpired(time() + 1800); CAdminNotify::Add(array( "MESSAGE" => GetMessage("BCL_CDN_NOTIFY_QUOTA_EXPIRED"), "TAG" => "bitrixcloud_off", "MODULE_ID" => "bitrixcloud", "ENABLE_CLOSE" => "N", )); self::$config->unlock(); return false; } } CAdminNotify::DeleteByTag("bitrixcloud_off"); return true; } /** * * @param string &$content * @return void * */ public static function OnEndBufferContent(&$content) { if (isset($_GET["nocdn"])) return; $appCache = \Bitrix\Main\Data\AppCacheManifest::getInstance(); if ($appCache->isEnabled()) return; self::$proto = CMain::IsHTTPS() ? "https" : "http"; self::$config = CBitrixCloudCDNConfig::getInstance()->loadFromOptions(); if (self::$config->isExpired()) { if(!self::updateConfig()) return; } if(!self::$config->isActive()) return; $sites = self::$config->getSites(); $siteId = defined("ADMIN_SECTION")? "admin": (defined("SITE_ID")? SITE_ID: ""); if (!isset($sites[$siteId])) return; self::$ajax = preg_match("/<head>/i", substr($content, 0, 1024)) === 0; $arPrefixes = array_map(array( "CBitrixCloudCDN", "_preg_quote", ), self::$config->getLocationsPrefixes(self::$config->isKernelRewriteEnabled(), self::$config->isContentRewriteEnabled())); $arExtensions = array_map(array( "CBitrixCloudCDN", "_preg_quote", ), self::$config->getLocationsExtensions()); if (!empty($arPrefixes) && !empty($arExtensions)) { $prefix_regex = "(?:".implode("|", $arPrefixes).")"; $extension_regex = "(?i:".implode("|", $arExtensions).")"; $regex = "/ ((?i: (?<!;)href= |(?<!;)src= |BX\\.loadCSS\\( |BX\\.loadScript\\( |BX\\.getCDNPath\\( |jsUtils\\.loadJSFile\\( |background\\s*:\\s*url\\( |image\\s*:\\s*url\\( |'SRC': )) #attribute (\"|') #open_quote (".$prefix_regex.") #prefix ([^?'\"]+\\.) #href body (".$extension_regex.") #extension (|\\?\\d+|\\?v=\\d+) #params (\\2) #close_quote /x"; $content = preg_replace_callback($regex, array( "CBitrixCloudCDN", "_filter", ), $content); } } /** * * @return void * */ public static function domainChanged() { self::$domain_changed = true; } /** * * @param string $str * @return string * */ private static function _preg_quote($str) { return preg_quote($str, "/"); } /** * * @param array[int]string $match * @return string * */ private static function _filter($match) { $attribute = $match[1]; $open_quote = $match[2]; $prefix = $match[3]; $link = $match[4]; $extension = $match[5]; $params = $match[6]; $close_quote = $match[7]; $location = /*.(CBitrixCloudCDNLocation).*/ null; if(self::$ajax && $extension === "js") return $match[0]; //if(preg_match("/^background/i", $attribute)) // $proto = self::$proto."://"; //else $proto = "//"; foreach (self::$config->getLocations() as $location) { /* @var CBitrixCloudCDNLocation $location */ if ($location->getProto() === self::$proto) { $server = $location->getServerNameByPrefixAndExtension($prefix, $extension, $link); if ($server !== "") { $filePath = $prefix.$link.$extension; if ($params === '') $filePath = CUtil::GetAdditionalFileURL($filePath); //Fix spaces in the link $link = str_replace(" ", "%20", $link); return $attribute.$open_quote.$proto.$server.$filePath.$params.$close_quote; } } } return $match[0]; } /** * Shows information about CDN free space in Admin's informer popup * * @return void */ public static function OnAdminInformerInsertItems() { global $USER; if (IsModuleInstalled('intranet')) return; $CDNAIParams = array( "TITLE" => GetMessage("BCL_CDN_AI_TITLE"), "COLOR" => "green", ); if (self::IsActive()) { if ($USER->CanDoOperation("bitrixcloud_cdn")) { $CDNAIParams["FOOTER"] = '<a href="/bitrix/admin/bitrixcloud_cdn.php?lang='.LANGUAGE_ID.'">'.GetMessage("BCL_CDN_AI_SETT").'</a>'; } $cdn_config = CBitrixCloudCDNConfig::getInstance()->loadFromOptions(); $cdn_quota = $cdn_config->getQuota(); $PROGRESS_TOTAL = $cdn_quota->getAllowedSize(); $PROGRESS_VALUE = $cdn_quota->getTrafficSize(); if ($PROGRESS_TOTAL > 0.0 || $PROGRESS_VALUE > 0.0) { $PROGRESS_AVAILABLE = $PROGRESS_TOTAL-$PROGRESS_VALUE; if($PROGRESS_AVAILABLE < 0.0) $PROGRESS_AVAILABLE = 0.0; $PROGRESS_FREE = 0.0; if($PROGRESS_TOTAL > 0.0) $PROGRESS_FREE = round(($PROGRESS_TOTAL-$PROGRESS_VALUE)/$PROGRESS_TOTAL*100); $PROGRESS_FREE_BAR = $PROGRESS_FREE > 100.0? 100: intval($PROGRESS_FREE); $PROGRESS_FREE_BAR = $PROGRESS_FREE < 0.0? 0: intval($PROGRESS_FREE_BAR); $CDNAIParams["ALERT"] = false; if ($PROGRESS_FREE < 10.0) $CDNAIParams["ALERT"] = true; elseif (!$cdn_config->isActive()) $CDNAIParams["ALERT"] = true; $CDNAIParams["HTML"] = ' <div class="adm-informer-item-section"> <span class="adm-informer-item-l"> <span class="adm-informer-strong-text">'.GetMessage("BCL_CDN_AI_USAGE_TOTAL").'</span> '.CFile::FormatSize($PROGRESS_TOTAL, 0).' </span> <span class="adm-informer-item-r"> <span class="adm-informer-strong-text">'.GetMessage("BCL_CDN_AI_USAGE_AVAIL").'</span> '.CFile::FormatSize($PROGRESS_AVAILABLE, 0).' </span> </div> <div class="adm-informer-status-bar-block" > <div class="adm-informer-status-bar-indicator" style="width:'.(100-$PROGRESS_FREE_BAR).'%; "></div> <div class="adm-informer-status-bar-text">'.(100-$PROGRESS_FREE).'%</div> </div> '; } } else { $CDNAIParams["HTML"] = ' <div class="adm-informer-item-section"> <span class="adm-informer-strong-text">'.GetMessage("BCL_CDN_AI_IS_OFF").'</span> </div> <div class="adm-informer-status-bar-block" > <div class="adm-informer-status-bar-indicator" style="width:0%; "></div> <div class="adm-informer-status-bar-text">0%</div> </div> '; $CDNAIParams["ALERT"] = true; if ($USER->CanDoOperation("bitrixcloud_cdn")) { $CDNAIParams["FOOTER"] = '<a href="/bitrix/admin/bitrixcloud_cdn.php?lang='.LANGUAGE_ID.'">'.GetMessage("BCL_CDN_AI_TURN_ON").'</a>'; } } CAdminInformer::AddItem($CDNAIParams); } }