更新
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Small response cache for the public app_games list pages.
|
||||
* Login state is loaded by the existing AJAX endpoint after this HTML is shown.
|
||||
*/
|
||||
function xxiaw_list_cache_page_number($server)
|
||||
{
|
||||
if (!isset($server['REQUEST_METHOD']) || strtoupper($server['REQUEST_METHOD']) !== 'GET') {
|
||||
return false;
|
||||
}
|
||||
$requestUri = isset($server['REQUEST_URI']) ? $server['REQUEST_URI'] : '';
|
||||
// Nginx adds the ThinkPHP route to QUERY_STRING during its internal rewrite.
|
||||
// REQUEST_URI keeps the browser's original URI, so use it to detect real args.
|
||||
if (strpos($requestUri, '?') !== false) {
|
||||
return false;
|
||||
}
|
||||
$path = parse_url($requestUri, PHP_URL_PATH);
|
||||
if (!is_string($path) || !preg_match('#^/app_games/index([1-9][0-9]*)[.]html$#D', rawurldecode($path), $matches)) {
|
||||
return false;
|
||||
}
|
||||
return intval($matches[1]);
|
||||
}
|
||||
|
||||
function xxiaw_list_cache_serve($file, $state)
|
||||
{
|
||||
$html = @file_get_contents($file);
|
||||
if ($html === false) {
|
||||
return false;
|
||||
}
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
header('X-Xxiaw-List-Cache: ' . $state);
|
||||
echo $html;
|
||||
return true;
|
||||
}
|
||||
|
||||
function xxiaw_list_cache_bootstrap()
|
||||
{
|
||||
if (PHP_SAPI === 'cli') {
|
||||
return false;
|
||||
}
|
||||
$page = xxiaw_list_cache_page_number($_SERVER);
|
||||
if ($page === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$ttl = 60;
|
||||
$staleTtl = 300;
|
||||
$cacheDir = dirname(__DIR__) . '/Runtime/XxiawListPageCache';
|
||||
if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0750, true) && !is_dir($cacheDir)) {
|
||||
return false;
|
||||
}
|
||||
$cacheFile = $cacheDir . '/app-games-page-' . $page . '.html';
|
||||
clearstatcache(true, $cacheFile);
|
||||
$modified = @filemtime($cacheFile);
|
||||
if ($modified !== false && $modified >= time() - $ttl && @filesize($cacheFile) > 1000) {
|
||||
if (xxiaw_list_cache_serve($cacheFile, 'HIT')) {
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$lock = @fopen($cacheFile . '.lock', 'c');
|
||||
if ($lock === false) {
|
||||
return false;
|
||||
}
|
||||
if (!@flock($lock, LOCK_EX | LOCK_NB)) {
|
||||
if ($modified !== false && $modified >= time() - $staleTtl && @filesize($cacheFile) > 1000) {
|
||||
@fclose($lock);
|
||||
if (xxiaw_list_cache_serve($cacheFile, 'STALE')) {
|
||||
exit;
|
||||
}
|
||||
}
|
||||
$deadline = microtime(true) + 0.20;
|
||||
do {
|
||||
usleep(20000);
|
||||
clearstatcache(true, $cacheFile);
|
||||
if (@filemtime($cacheFile) >= time() - $ttl && @filesize($cacheFile) > 1000) {
|
||||
@fclose($lock);
|
||||
if (xxiaw_list_cache_serve($cacheFile, 'HIT')) {
|
||||
exit;
|
||||
}
|
||||
}
|
||||
} while (microtime(true) < $deadline);
|
||||
@fclose($lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
header('X-Xxiaw-List-Cache: MISS');
|
||||
ob_start(function ($html) use ($cacheDir, $cacheFile, $lock) {
|
||||
$status = http_response_code();
|
||||
if (($status === false || $status < 400) && strlen($html) > 1000 && strpos($html, 'class="jshwarticle"') !== false) {
|
||||
$temporary = @tempnam($cacheDir, '.list-cache-');
|
||||
if ($temporary !== false) {
|
||||
if (@file_put_contents($temporary, $html, LOCK_EX) !== false) {
|
||||
@chmod($temporary, 0640);
|
||||
@rename($temporary, $cacheFile);
|
||||
}
|
||||
if (is_file($temporary)) {
|
||||
@unlink($temporary);
|
||||
}
|
||||
}
|
||||
}
|
||||
@flock($lock, LOCK_UN);
|
||||
@fclose($lock);
|
||||
return $html;
|
||||
});
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user