13 private static $error =
null;
14 private static $errorMessage =
null;
22 require_once(__DIR__.
"/helper.php");
24 self::setErrorHandler();
25 self::registerAutoloader();
27 self::modifyHttpHeaders();
29 if (self::isValidRequest())
33 self::trySendResponse();
36 define(
"USE_HTML_STATIC_CACHE",
true);
39 self::unregisterAutoloader();
40 self::restoreErrorHandler();
43 private static function isValidRequest()
46 isset($_SERVER[
"HTTP_BX_AJAX"]) ||
47 isset($_GET[
"bxajaxid"]) ||
48 (isset($_SERVER[
"HTTP_X_REQUESTED_WITH"]) && $_SERVER[
"HTTP_X_REQUESTED_WITH"] ===
"XMLHttpRequest")
51 self::$error = Logger::TYPE_AJAX_REQUEST;
55 if (isset($_GET[
"ncc"]))
57 self::$error = Logger::TYPE_NCC_PARAMETER;
63 self::$error = Logger::TYPE_BITRIX_FOLDER;
67 if (preg_match(
"#^/index_controller\\.php#", $_SERVER[
"REQUEST_URI"]) > 0)
69 self::$error = Logger::TYPE_CONTROLLER_FILE;
74 define(
"ENABLE_HTML_STATIC_CACHE_JS",
true);
76 if ($_SERVER[
"REQUEST_METHOD"] !==
"GET")
78 self::$error = Logger::TYPE_GET_METHOD_ONLY;
79 self::$errorMessage =
"Request Method: ".$_SERVER[
"REQUEST_METHOD"];
83 if (isset($_GET[
"sessid"]))
85 self::$error = Logger::TYPE_SESSID_PARAMETER;
92 if (isset($compositeOptions[
"COOKIE_NCC"]) &&
93 array_key_exists($compositeOptions[
"COOKIE_NCC"], $_COOKIE) &&
94 $_COOKIE[$compositeOptions[
"COOKIE_NCC"]] ===
"Y"
97 self::$error = Logger::TYPE_NCC_COOKIE;
103 isset($compositeOptions[
"STORE_PASSWORD"]) &&
104 $compositeOptions[
"STORE_PASSWORD"] ==
"Y" &&
105 isset($_COOKIE[$compositeOptions[
"COOKIE_LOGIN"]]) &&
106 $_COOKIE[$compositeOptions[
"COOKIE_LOGIN"]] !==
"" &&
107 isset($_COOKIE[$compositeOptions[
"COOKIE_PASS"]]) &&
108 $_COOKIE[$compositeOptions[
"COOKIE_PASS"]] !==
""
112 !isset($compositeOptions[
"COOKIE_CC"]) ||
113 !array_key_exists($compositeOptions[
"COOKIE_CC"], $_COOKIE) ||
114 $_COOKIE[$compositeOptions[
"COOKIE_CC"]] !==
"Y"
117 self::$error = Logger::TYPE_CC_COOKIE_NOT_FOUND;
122 $queryPos = mb_strpos($_SERVER[
"REQUEST_URI"],
"?");
123 $requestUri = $queryPos ===
false? $_SERVER[
"REQUEST_URI"] : mb_substr($_SERVER[
"REQUEST_URI"], 0, $queryPos);
126 if (isset($compositeOptions[
"~EXCLUDE_MASK"]) && is_array($compositeOptions[
"~EXCLUDE_MASK"]))
128 foreach ($compositeOptions[
"~EXCLUDE_MASK"] as $mask)
130 if (preg_match($mask, $requestUri) > 0)
132 self::$error = Logger::TYPE_EXCLUDE_MASK;
133 self::$errorMessage =
"Mask: ".$mask;
140 if (isset($compositeOptions[
"~EXCLUDE_PARAMS"]) && is_array($compositeOptions[
"~EXCLUDE_PARAMS"]))
142 foreach ($compositeOptions[
"~EXCLUDE_PARAMS"] as $param)
144 if (array_key_exists($param, $_GET))
146 self::$error = Logger::TYPE_EXCLUDE_PARAMETER;
147 self::$errorMessage =
"Parameter: ".$param;
154 $isRequestInMask =
false;
155 if (isset($compositeOptions[
"~INCLUDE_MASK"]) && is_array($compositeOptions[
"~INCLUDE_MASK"]))
157 foreach ($compositeOptions[
"~INCLUDE_MASK"] as $mask)
159 if (preg_match($mask, $requestUri) > 0)
161 $isRequestInMask =
true;
167 if (!$isRequestInMask)
169 self::$error = Logger::TYPE_INCLUDE_MASK;
177 self::$error = Logger::TYPE_INVALID_HOST;
178 self::$errorMessage =
"Host: ".$host;
182 if (!self::isValidQueryString($compositeOptions))
184 self::$error = Logger::TYPE_INVALID_QUERY_STRING;
194 private static function trySendResponse()
196 $cacheKey = self::getCacheKey();
197 $cache = self::getHtmlCacheResponse($cacheKey);
198 if ($cache ===
null || !$cache->exists())
205 $etag = $cache->getEtag();
206 $lastModified = $cache->getLastModified();
209 if (array_key_exists(
"HTTP_IF_NONE_MATCH", $_SERVER) && $_SERVER[
"HTTP_IF_NONE_MATCH"] === $etag)
211 self::setStatus(
"304 Not Modified");
212 self::setHeaders($etag,
false,
"304");
217 if ($lastModified !==
false)
220 isset($_SERVER[
"HTTP_IF_MODIFIED_SINCE"]) ?
221 strtotime($_SERVER[
"HTTP_IF_MODIFIED_SINCE"]) :
224 if ($sinceModified && $sinceModified >= $lastModified)
226 self::setStatus(
"304 Not Modified");
227 self::setHeaders($etag,
false,
"304");
232 $contents = $cache->getContents();
233 if ($contents !==
false)
235 self::setHeaders($etag, $lastModified,
"200", $cache->getContentType());
239 if ($compositeOptions[
"COMPRESS"] && isset($_SERVER[
"HTTP_ACCEPT_ENCODING"]))
241 if (strpos($_SERVER[
"HTTP_ACCEPT_ENCODING"],
"x-gzip") !==
false)
243 $compress =
"x-gzip";
245 elseif (strpos($_SERVER[
"HTTP_ACCEPT_ENCODING"],
"gzip") !==
false)
253 header(
"Content-Encoding: ".$compress);
254 echo $cache->isGzipped() ? $contents : gzencode($contents, 4);
258 if ($cache->isGzipped())
263 header(
"Content-Length: " . strlen($contents));
271 private static function modifyHttpHeaders()
275 if (isset($_SERVER[
"HTTP_BX_REF"]))
277 $_SERVER[
"HTTP_REFERER"] = $_SERVER[
"HTTP_BX_REF"];
290 private static function setHeaders($etag, $lastModified, $compositeHeader =
false, $contentType =
false)
294 header(
"ETag: ".$etag);
297 header(
"Expires: Fri, 07 Jun 1974 04:00:00 GMT");
299 if ($lastModified !==
false)
301 $utc = gmdate(
"D, d M Y H:i:s", $lastModified).
" GMT";
302 header(
"Last-Modified: ".$utc);
305 if ($contentType !==
false)
307 header(
"Content-type: ".$contentType);
310 if ($compositeHeader !==
false)
312 header(
"X-Bitrix-Composite: Cache (".$compositeHeader.
")");
321 private static function setStatus($status)
323 $bCgi = (mb_stristr(php_sapi_name(),
"cgi") !==
false);
324 $bFastCgi = ($bCgi && (array_key_exists(
"FCGI_ROLE", $_SERVER) || array_key_exists(
"FCGI_ROLE", $_ENV)));
325 if ($bCgi && !$bFastCgi)
327 header(
"Status: ".$status);
331 header($_SERVER[
"SERVER_PROTOCOL"].
" ".$status);
335 private static function isValidQueryString($compositeOptions)
337 if (!isset($compositeOptions[
"INDEX_ONLY"]) || !$compositeOptions[
"INDEX_ONLY"])
343 if (isset($_SERVER[
"REQUEST_URI"]) && ($position = mb_strpos($_SERVER[
"REQUEST_URI"],
"?")) !==
false)
345 $queryString = mb_substr($_SERVER[
"REQUEST_URI"], $position + 1);
349 if ($queryString ===
"")
354 $queryParams = array();
355 parse_str($queryString, $queryParams);
356 if (isset($compositeOptions[
"~GET"]) &&
357 !empty($compositeOptions[
"~GET"]) &&
358 empty(array_diff(array_keys($queryParams), $compositeOptions[
"~GET"]))
372 private static function getCacheKey()
390 private static function getHtmlCacheResponse($cacheKey)
392 $configuration = array();
394 $storage = $compositeOptions[
"STORAGE"] ??
false;
395 if (in_array($storage, array(
"memcached",
"memcached_cluster")))
397 if (extension_loaded(
"memcache"))
399 return new MemcachedResponse($cacheKey, $configuration, $compositeOptions);
408 return new FileResponse($cacheKey, $configuration, $compositeOptions);
412 private static function registerAutoloader()
414 \spl_autoload_register(array(__CLASS__,
"autoLoad"),
true);
417 private static function unregisterAutoloader()
419 \spl_autoload_unregister(array(__CLASS__,
"autoLoad"));
424 $className = ltrim($className,
"\\");
425 if ($className ===
"Bitrix\\Main\\Composite\\Debug\\Logger")
427 require_once(__DIR__.
"/debug/logger.php");
448 return self::$errorMessage;
451 private static function setErrorHandler()
453 set_error_handler(array(__CLASS__,
"handleError"));
456 private static function restoreErrorHandler()
458 restore_error_handler();
__construct($cacheKey, array $configuration, array $htmlCacheOptions)
__construct($cacheKey, array $configuration, array $htmlCacheOptions)
static convertUriToPath($uri, $host=null, $privateKey=null)
static getRealPrivateKey($privateKey=null, $postfix=null)
__construct($cacheKey, array $configuration, array $htmlCacheOptions)