日志升级与缓存修复最终版
This commit is contained in:
Executable
+30
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/** 回归:白名单 IP 快速路径 */
|
||||
define('SHOW_SITE_MODE_SWITCH', 'ip_check');
|
||||
define('SHOW_SITE_IP', '8.8.8.8');
|
||||
define('BLACKLIST_GROUP_ID', 0);
|
||||
define('WHITELIST_GROUP_ID', 0);
|
||||
define('SHOW_SITE_COUNTRY', 'US');
|
||||
define('CLOAK_SHOW_CONTENT', '302');
|
||||
define('DB_FP', ['https://example.com/fp']);
|
||||
define('COSTM_IP_SCORE', 'test');
|
||||
define('BLACK_LIST', '0');
|
||||
define('AUTO_BLACK', 'OFF');
|
||||
define('IS_VIRTUAL', '0');
|
||||
define('AUTO_BLACK_TIMES', '5');
|
||||
define('WHITE_PARAMS', '');
|
||||
define('IPHONE_MODEL', 0);
|
||||
define('SHOW_SITE_MOBILE', 0);
|
||||
define('SHOW_SITE_OUTPUT', 1);
|
||||
define('WRITE_LOG', 0);
|
||||
define('CLOAK_ZH_ON', 'OFF');
|
||||
define('CLOAK_OS_ON', 'OFF');
|
||||
define('KEEP_PARAMS', 'OFF');
|
||||
define('CLOAK_REDIRECT_METHOD', '302');
|
||||
define('DB_ZP', 'https://example.com/zp');
|
||||
define('CLOAK_MOBILE_ON', 'OFF');
|
||||
define('CLOAK_V_REFERER', 'OFF');
|
||||
define('CLOAK_RISK_NUMBER', '0');
|
||||
define('CLOAK_RISK_ENHANCED', 'OFF');
|
||||
define('CLOAK_URL_ARGS_TIMEOUT', '0');
|
||||
define('CLOAK_DEBUG_MODE', 'OFF');
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/** 回归:正品模式下白名单 IP 仍应走真实页判定 */
|
||||
define('SHOW_SITE_MODE_SWITCH', 'zp');
|
||||
define('SHOW_SITE_IP', '8.8.8.8');
|
||||
define('BLACKLIST_GROUP_ID', 0);
|
||||
define('WHITELIST_GROUP_ID', 0);
|
||||
define('SHOW_SITE_COUNTRY', 'US');
|
||||
define('CLOAK_SHOW_CONTENT', '302');
|
||||
define('DB_FP', ['https://example.com/fp']);
|
||||
define('COSTM_IP_SCORE', 'test');
|
||||
define('BLACK_LIST', '0');
|
||||
define('AUTO_BLACK', 'OFF');
|
||||
define('IS_VIRTUAL', '0');
|
||||
define('AUTO_BLACK_TIMES', '5');
|
||||
define('WHITE_PARAMS', '');
|
||||
define('IPHONE_MODEL', 0);
|
||||
define('SHOW_SITE_MOBILE', 0);
|
||||
define('SHOW_SITE_OUTPUT', 1);
|
||||
define('WRITE_LOG', 0);
|
||||
define('CLOAK_ZH_ON', 'OFF');
|
||||
define('CLOAK_OS_ON', 'OFF');
|
||||
define('KEEP_PARAMS', 'OFF');
|
||||
define('CLOAK_REDIRECT_METHOD', '302');
|
||||
define('DB_ZP', 'https://example.com/zp');
|
||||
define('CLOAK_MOBILE_ON', 'OFF');
|
||||
define('CLOAK_V_REFERER', 'OFF');
|
||||
define('CLOAK_RISK_NUMBER', '0');
|
||||
define('CLOAK_RISK_ENHANCED', 'OFF');
|
||||
define('CLOAK_URL_ARGS_TIMEOUT', '0');
|
||||
define('CLOAK_DEBUG_MODE', 'OFF');
|
||||
@@ -137,6 +137,11 @@ reg_assert('fp 模式配置生效', ($fpResult['mode'] ?? '') === 'fp', json_enc
|
||||
|
||||
$zpResult = run_pipeline_subprocess($root, 'regression_zp.php');
|
||||
reg_assert('zp 模式配置生效', ($zpResult['mode'] ?? '') === 'zp', json_encode($zpResult, JSON_UNESCAPED_UNICODE));
|
||||
reg_assert('zp 模式判定 false + 正品模式', ($zpResult['result'] ?? null) === 'false' && ($zpResult['reason'] ?? '') === '正品模式', json_encode($zpResult, JSON_UNESCAPED_UNICODE));
|
||||
|
||||
$earlyRouteOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_early_route_gate.php') . ' 2>/dev/null');
|
||||
$earlyRouteJson = json_decode((string) $earlyRouteOut, true);
|
||||
reg_assert('白名单/正品早期快速路径', ($earlyRouteJson['ok'] ?? false) === true, (string) $earlyRouteOut);
|
||||
|
||||
// ── 7. 指纹跳转模板 ───────────────────────────────────────────
|
||||
echo "[7] 指纹跳转模板\n";
|
||||
@@ -158,12 +163,17 @@ reg_assert('cloak_fingerprint_cookies_ready', cloak_fingerprint_cookies_ready())
|
||||
$_SERVER['HTTP_HOST'] = 'shop.example.com';
|
||||
reg_assert('cloak_fingerprint_cookie_domain', cloak_fingerprint_cookie_domain() === '.example.com');
|
||||
|
||||
$cookieDomainOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_cookie_domain.php') . ' 2>/dev/null');
|
||||
$cookieDomainJson = json_decode((string) $cookieDomainOut, true);
|
||||
reg_assert('Cookie 域推断与 JS 选项', ($cookieDomainJson['ok'] ?? false) === true, (string) $cookieDomainOut);
|
||||
|
||||
$_GET = ['c' => 'index'];
|
||||
ob_start();
|
||||
include $root . '/dist/index.php';
|
||||
$distJs = ob_get_clean();
|
||||
reg_assert('dist/index.php 输出 Cookies.set', strpos($distJs, "fpCookies.set('ctime'") !== false);
|
||||
reg_assert('dist/index.php 输出指纹完成回调', strpos($distJs, '__cloakFingerprintDone') !== false);
|
||||
reg_assert('dist/index.php 输出 sameSite Lax', strpos($distJs, '"sameSite":"Lax"') !== false || strpos($distJs, '"sameSite": "Lax"') !== false);
|
||||
reg_assert('dist/index.php 无 PHP Fatal', stripos($distJs, 'Fatal error') === false);
|
||||
|
||||
$virtualDetectOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_virtual_detect.php') . ' 2>/dev/null');
|
||||
@@ -234,10 +244,30 @@ $riskCacheOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($ro
|
||||
$riskCacheJson = json_decode((string) $riskCacheOut, true);
|
||||
reg_assert('二次风控 Session 缓存与 CORS', ($riskCacheJson['ok'] ?? false) === true, (string) $riskCacheOut);
|
||||
|
||||
$judgmentCacheOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_client_judgment_cache.php') . ' 2>/dev/null');
|
||||
$judgmentCacheJson = json_decode((string) $judgmentCacheOut, true);
|
||||
reg_assert('客户端 Session 统一缓存策略', ($judgmentCacheJson['ok'] ?? false) === true, (string) $judgmentCacheOut);
|
||||
|
||||
$datalistHelperOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_datalist_helper.php') . ' 2>/dev/null');
|
||||
$datalistHelperJson = json_decode((string) $datalistHelperOut, true);
|
||||
reg_assert('日志列表 VisitorLogListHelper', ($datalistHelperJson['ok'] ?? false) === true, (string) $datalistHelperOut);
|
||||
|
||||
$riskSessionOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_risk_session.php') . ' 2>/dev/null');
|
||||
$riskSessionJson = json_decode((string) $riskSessionOut, true);
|
||||
reg_assert('二次风控 Session 防重复写库', ($riskSessionJson['ok'] ?? false) === true, (string) $riskSessionOut);
|
||||
|
||||
$judgmentPriOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_judgment_priority.php') . ' 2>/dev/null');
|
||||
$judgmentPriJson = json_decode((string) $judgmentPriOut, true);
|
||||
reg_assert('判定优先级顺序', ($judgmentPriJson['ok'] ?? false) === true, (string) $judgmentPriOut);
|
||||
|
||||
$visitLogOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_visit_log_lifecycle.php') . ' 2>/dev/null');
|
||||
$visitLogJson = json_decode((string) $visitLogOut, true);
|
||||
reg_assert('Visit 生命周期与 reason 规范化', ($visitLogJson['ok'] ?? false) === true, (string) $visitLogOut);
|
||||
|
||||
$waitLogOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_wait_log_write.php') . ' 2>/dev/null');
|
||||
$waitLogJson = json_decode((string) $waitLogOut, true);
|
||||
reg_assert('二次风控 wait 日志同步完整落库', ($waitLogJson['ok'] ?? false) === true, (string) $waitLogOut);
|
||||
|
||||
// ── 12. ConfigLoader / 宝塔部署文件 ───────────────────────────
|
||||
echo "[12] ConfigLoader 与宝塔部署\n";
|
||||
require_once $root . '/config/ConfigLoader.php';
|
||||
|
||||
Executable
+97
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* 客户端 Session 统一缓存策略回归
|
||||
*/
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$root = dirname(__DIR__);
|
||||
require_once $root . '/cong.php';
|
||||
require_once $root . '/lib/Cloak/RiskSecondaryGate.php';
|
||||
require_once $root . '/lib/Cloak/CloakJudgmentCache.php';
|
||||
|
||||
if (!defined('CLOAK_RISK_NUMBER')) {
|
||||
define('CLOAK_RISK_NUMBER', 51);
|
||||
}
|
||||
if (!defined('COSTM_IP_SCORE')) {
|
||||
define('COSTM_IP_SCORE', 'judgment_cache_test');
|
||||
}
|
||||
|
||||
$_SESSION = [];
|
||||
$tests = [];
|
||||
|
||||
// byApi + 风险开启 → partial
|
||||
CloakJudgmentCache::storeFromByApi([
|
||||
'ip' => '10.0.0.1',
|
||||
'country' => 'US',
|
||||
'result' => 'true',
|
||||
'reason' => 'api pass',
|
||||
]);
|
||||
$tests['byapi_with_risk_is_partial'] = CloakJudgmentCache::isPartial();
|
||||
$tests['partial_not_final'] = !CloakJudgmentCache::isFinal();
|
||||
$tests['partial_fast_path_miss'] = CloakJudgmentCache::getFinal() === null;
|
||||
|
||||
$cachedPartial = CloakJudgmentCache::get();
|
||||
if (CloakJudgmentCache::isPartial($cachedPartial)) {
|
||||
CloakJudgmentCache::applyToSession($cachedPartial);
|
||||
$_SESSION['visit_to_2'] = '2';
|
||||
}
|
||||
$tests['partial_resume_hit'] = CloakJudgmentCache::isPartial($cachedPartial);
|
||||
$tests['partial_resume_sets_visit_to_2'] = ($_SESSION['visit_to_2'] ?? '') === '2';
|
||||
$tests['partial_keeps_visit_to_3_open'] = ($_SESSION['visit_to_3'] ?? '') === '1';
|
||||
|
||||
// byApi false → final even with risk
|
||||
$_SESSION = [];
|
||||
CloakJudgmentCache::storeFromByApi([
|
||||
'ip' => '10.0.0.2',
|
||||
'country' => 'US',
|
||||
'result' => 'false',
|
||||
'reason' => 'api deny',
|
||||
]);
|
||||
$tests['byapi_false_is_final'] = CloakJudgmentCache::isFinal();
|
||||
|
||||
// byApiRisk → final
|
||||
$_SESSION = [];
|
||||
CloakJudgmentCache::storeFromByApiRisk([
|
||||
'ip' => '10.0.0.3',
|
||||
'country' => 'CA',
|
||||
'result' => 'true',
|
||||
'reason' => '',
|
||||
'fp_url' => 'https://fp/x',
|
||||
]);
|
||||
$finalCached = CloakJudgmentCache::getFinal();
|
||||
$tests['final_fast_path_hit'] = $finalCached !== null;
|
||||
if (is_array($finalCached)) {
|
||||
CloakJudgmentCache::applyToSession($finalCached);
|
||||
}
|
||||
$tests['final_applies_check_result'] = ($_SESSION['check_result'] ?? '') === 'true';
|
||||
|
||||
// 无 Session 缓存
|
||||
$_SESSION = [];
|
||||
$tests['empty_session_no_cache'] = CloakJudgmentCache::get() === null;
|
||||
|
||||
$noRiskCmd = escapeshellarg(PHP_BINARY) . ' -r ' . escapeshellarg(
|
||||
'define("CLOAK_RISK_NUMBER",0);'
|
||||
. 'require ' . var_export($root . '/lib/Cloak/RiskSecondaryGate.php', true) . ';'
|
||||
. 'require ' . var_export($root . '/lib/Cloak/CloakJudgmentCache.php', true) . ';'
|
||||
. '$_SESSION=[];'
|
||||
. 'CloakJudgmentCache::storeFromByApi(["ip"=>"10.0.0.4","country"=>"US","result"=>"true","reason"=>""]);'
|
||||
. '$c=$_SESSION["cloak_judgment_cache"]??[];'
|
||||
. 'echo (CloakJudgmentCache::isFinal() && ($c["stage"]??"")==="final" && CloakJudgmentCache::getFinal()!==null) ? "1" : "0";'
|
||||
);
|
||||
$tests['byapi_no_risk_is_final'] = trim((string) shell_exec($noRiskCmd)) === '1';
|
||||
|
||||
$legacyByapiCmd = escapeshellarg(PHP_BINARY) . ' -r ' . escapeshellarg(
|
||||
'define("CLOAK_RISK_NUMBER",0);'
|
||||
. 'require ' . var_export($root . '/lib/Cloak/RiskSecondaryGate.php', true) . ';'
|
||||
. 'require ' . var_export($root . '/lib/Cloak/CloakJudgmentCache.php', true) . ';'
|
||||
. '$_SESSION=["cloak_judgment_cache"=>["stage"=>"byapi","ip"=>"10.0.0.5","country"=>"US","result"=>"true","reason"=>"","fp_url"=>"","risk_number"=>0,"campaign_id"=>"x","cached_at"=>1]];'
|
||||
. 'echo (CloakJudgmentCache::isFinal() && CloakJudgmentCache::getFinal()!==null && !CloakJudgmentCache::isPartial()) ? "1" : "0";'
|
||||
);
|
||||
$tests['risk_zero_treats_legacy_byapi_as_final'] = trim((string) shell_exec($legacyByapiCmd)) === '1';
|
||||
|
||||
$ok = !in_array(false, $tests, true);
|
||||
echo json_encode(['ok' => $ok, 'tests' => $tests], JSON_UNESCAPED_UNICODE) . "\n";
|
||||
exit($ok ? 0 : 1);
|
||||
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* Cookie 域推断与指纹 JS 选项回归(CLI JSON)
|
||||
*/
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$root = dirname(__DIR__);
|
||||
require_once $root . '/lib/CloakHttpHelpers.php';
|
||||
|
||||
$tests = [];
|
||||
|
||||
$cases = [
|
||||
['shop.example.com', '.example.com'],
|
||||
['shop.example.com:443', '.example.com'],
|
||||
['SHOP.Example.COM:8080', '.example.com'],
|
||||
['shili.buzz', '.shili.buzz'],
|
||||
['www.shili.buzz', '.shili.buzz'],
|
||||
['a.b.shili.buzz', '.shili.buzz'],
|
||||
['shop.foo.co.uk', '.foo.co.uk'],
|
||||
['www.shop.foo.co.uk', '.foo.co.uk'],
|
||||
['127.0.0.1', ''],
|
||||
['[::1]', ''],
|
||||
['localhost', ''],
|
||||
['cloaka.test', ''],
|
||||
['single', ''],
|
||||
];
|
||||
|
||||
foreach ($cases as $i => $case) {
|
||||
$_SERVER['HTTP_HOST'] = $case[0];
|
||||
$tests['domain_' . $i] = cloak_fingerprint_cookie_domain() === $case[1];
|
||||
}
|
||||
|
||||
$_SERVER['HTTP_HOST'] = 'shop.example.com';
|
||||
$_SERVER['HTTPS'] = 'on';
|
||||
$jsOpts = cloak_fingerprint_js_cookie_options();
|
||||
$tests['js_opts_domain'] = ($jsOpts['domain'] ?? '') === '.example.com';
|
||||
$tests['js_opts_secure_https'] = !empty($jsOpts['secure']);
|
||||
$tests['js_opts_samesite'] = ($jsOpts['sameSite'] ?? '') === 'Lax';
|
||||
|
||||
$_SERVER['HTTPS'] = 'off';
|
||||
unset($_SERVER['HTTP_X_FORWARDED_PROTO']);
|
||||
$jsOptsHttp = cloak_fingerprint_js_cookie_options();
|
||||
$tests['js_opts_no_secure_http'] = empty($jsOptsHttp['secure']);
|
||||
|
||||
if (!defined('CLOAK_COOKIE_DOMAIN')) {
|
||||
define('CLOAK_COOKIE_DOMAIN', '.fixed.buzz');
|
||||
}
|
||||
$_SERVER['HTTP_HOST'] = 'other.example.com';
|
||||
$tests['config_override'] = cloak_fingerprint_cookie_domain() === '.fixed.buzz';
|
||||
|
||||
$ok = !in_array(false, $tests, true);
|
||||
echo json_encode(['ok' => $ok, 'tests' => $tests], JSON_UNESCAPED_UNICODE) . "\n";
|
||||
exit($ok ? 0 : 1);
|
||||
Regular → Executable
+9
@@ -23,6 +23,15 @@ if ($conn->connect_error) {
|
||||
$where = VisitorLogListHelper::buildWhere($conn, ['visit_date' => '2026-01-15']);
|
||||
$tests['date_range_where'] = strpos($where, 'visit_date') !== false && strpos($where, 'DATE_FORMAT') === false;
|
||||
|
||||
$whereAll = VisitorLogListHelper::buildWhere($conn, []);
|
||||
$tests['default_includes_wait'] = strpos($whereAll, 'wait') === false;
|
||||
|
||||
$whereWait = VisitorLogListHelper::buildWhere($conn, ['result' => 'wait']);
|
||||
$tests['filter_wait'] = strpos($whereWait, "`result` = 'wait'") !== false;
|
||||
|
||||
$whereWaitCn = VisitorLogListHelper::buildWhere($conn, ['result' => '检测中']);
|
||||
$tests['filter_wait_cn'] = strpos($whereWaitCn, "`result` = 'wait'") !== false;
|
||||
|
||||
$sql = VisitorLogListHelper::listSelectSql('1', 0, 10, true);
|
||||
$tests['lean_select_no_fp_hdata'] = strpos($sql, '`fp_hdata`,') === false && strpos($sql, 'has_fp_hdata') !== false;
|
||||
|
||||
|
||||
Executable
+82
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/**
|
||||
* 白名单 / 正品模式早期快速路径验证
|
||||
* 输出 JSON:{ok, checks: [...]}
|
||||
*/
|
||||
$root = dirname(__DIR__);
|
||||
require_once $root . '/cong.php';
|
||||
require_once $root . '/lib/bootstrap.php';
|
||||
|
||||
$checks = [];
|
||||
|
||||
function check_gate($name, $cond, $detail = '')
|
||||
{
|
||||
global $checks;
|
||||
$checks[] = ['name' => $name, 'ok' => (bool) $cond, 'detail' => $detail];
|
||||
}
|
||||
|
||||
function run_pipeline_fixture($root, $fixtureName)
|
||||
{
|
||||
$fixture = $root . '/tools/fixtures/' . $fixtureName;
|
||||
$cmd = escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/run_pipeline_fixture.php')
|
||||
. ' ' . escapeshellarg($fixture) . ' 2>&1';
|
||||
exec($cmd, $out, $code);
|
||||
$json = json_decode(implode("\n", $out), true);
|
||||
|
||||
return is_array($json) ? $json : ['error' => implode("\n", $out), 'code' => $code];
|
||||
}
|
||||
|
||||
// WhitelistGate(独立子进程,避免常量冲突)
|
||||
$gateCmd = escapeshellarg(PHP_BINARY) . ' -r ' . escapeshellarg(
|
||||
'define("SHOW_SITE_IP","8.8.8.8");define("WHITE_PARAMS","token=abc");define("WHITELIST_GROUP_ID",0);'
|
||||
. 'require ' . var_export($root . '/lib/bootstrap.php', true) . ';'
|
||||
. '$_GET=["token"=>"abc"];'
|
||||
. 'echo json_encode(["ip"=>WhitelistGate::matchesWhitelistIp("8.8.8.8"),"param"=>WhitelistGate::matchesWhitelistParams()]);'
|
||||
);
|
||||
$gateJson = json_decode((string) shell_exec($gateCmd), true);
|
||||
check_gate('WhitelistGate IP/参数', ($gateJson['ip'] ?? false) && ($gateJson['param'] ?? false));
|
||||
|
||||
$zp = run_pipeline_fixture($root, 'regression_zp.php');
|
||||
check_gate(
|
||||
'zp 模式仅记录国家并判定 false',
|
||||
($zp['mode'] ?? '') === 'zp'
|
||||
&& ($zp['result'] ?? null) === 'false'
|
||||
&& ($zp['reason'] ?? '') === '正品模式',
|
||||
json_encode($zp, JSON_UNESCAPED_UNICODE)
|
||||
);
|
||||
|
||||
$wl = run_pipeline_fixture($root, 'regression_whitelist_fast.php');
|
||||
check_gate(
|
||||
'白名单快速路径判定 true',
|
||||
($wl['result'] ?? null) === 'true',
|
||||
json_encode($wl, JSON_UNESCAPED_UNICODE)
|
||||
);
|
||||
|
||||
$zpWl = run_pipeline_fixture($root, 'regression_zp_whitelist.php');
|
||||
check_gate(
|
||||
'zp 模式下白名单仍判定 true',
|
||||
($zpWl['mode'] ?? '') === 'zp'
|
||||
&& ($zpWl['result'] ?? null) === 'true',
|
||||
json_encode($zpWl, JSON_UNESCAPED_UNICODE)
|
||||
);
|
||||
|
||||
$simOut = shell_exec(escapeshellarg(PHP_BINARY) . ' ' . escapeshellarg($root . '/tools/verify_simulation_zp_whitelist_route.php') . ' 2>/dev/null');
|
||||
$simJson = null;
|
||||
if (preg_match('/\{.*\}\s*$/s', (string) $simOut, $m)) {
|
||||
$simJson = json_decode($m[0], true);
|
||||
}
|
||||
check_gate(
|
||||
'SimulationRouteResolver zp+白名单走真实页',
|
||||
($simJson['ok'] ?? false) === true,
|
||||
(string) $simOut
|
||||
);
|
||||
|
||||
$ok = true;
|
||||
foreach ($checks as $c) {
|
||||
if (!$c['ok']) {
|
||||
$ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode(['ok' => $ok, 'checks' => $checks], JSON_UNESCAPED_UNICODE);
|
||||
Executable
+84
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* 判定优先级顺序回归
|
||||
*/
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$root = dirname(__DIR__);
|
||||
require_once $root . '/cong.php';
|
||||
require_once $root . '/lib/Cloak/WhitelistGate.php';
|
||||
require_once $root . '/lib/Cloak/RiskSecondaryGate.php';
|
||||
require_once $root . '/lib/Cloak/CloakJudgmentCache.php';
|
||||
require_once $root . '/lib/Cloak/Pipeline/CheckPipeline.php';
|
||||
|
||||
if (!defined('WHITE_PARAMS')) {
|
||||
define('WHITE_PARAMS', 'token=abc');
|
||||
}
|
||||
if (!defined('SHOW_SITE_IP')) {
|
||||
define('SHOW_SITE_IP', '8.8.8.8');
|
||||
}
|
||||
if (!defined('BLACKLIST_GROUP_ID')) {
|
||||
define('BLACKLIST_GROUP_ID', 0);
|
||||
}
|
||||
|
||||
$tests = [];
|
||||
|
||||
$_GET = ['token' => 'abc'];
|
||||
$tests['params_whitelist_fast'] = CheckPipeline::resolveWhitelistParamsFastPath();
|
||||
|
||||
$_GET = [];
|
||||
$_SERVER['REMOTE_ADDR'] = '8.8.8.8';
|
||||
$tests['ip_whitelist_when_no_params'] = CheckPipeline::resolveWhitelistIpFastPath();
|
||||
|
||||
$_GET = ['token' => 'abc'];
|
||||
$tests['match_reason_params_first'] = WhitelistGate::matchReason((object) ['v_ip' => '8.8.8.8']) === '白名单链接参数';
|
||||
$_GET = [];
|
||||
$tests['match_reason_ip'] = WhitelistGate::matchReason((object) ['v_ip' => '8.8.8.8']) === '白名单';
|
||||
|
||||
$zpCmd = escapeshellarg(PHP_BINARY) . ' -r ' . escapeshellarg(
|
||||
'define("SHOW_SITE_MODE_SWITCH","zp");'
|
||||
. 'require ' . var_export($root . '/lib/Cloak/Pipeline/CheckPipeline.php', true) . ';'
|
||||
. 'echo CheckPipeline::resolveZpFastPath() ? "1" : "0";'
|
||||
);
|
||||
$fpCmd = escapeshellarg(PHP_BINARY) . ' -r ' . escapeshellarg(
|
||||
'define("SHOW_SITE_MODE_SWITCH","fp");'
|
||||
. 'require ' . var_export($root . '/lib/Cloak/Pipeline/CheckPipeline.php', true) . ';'
|
||||
. 'echo CheckPipeline::resolveFpFastPath() ? "1" : "0";'
|
||||
);
|
||||
$cacheCmd = escapeshellarg(PHP_BINARY) . ' -r ' . escapeshellarg(
|
||||
'define("SHOW_SITE_MODE_SWITCH","ip_check");'
|
||||
. 'define("CLOAK_RISK_NUMBER",0);'
|
||||
. 'require ' . var_export($root . '/lib/Cloak/CloakJudgmentCache.php', true) . ';'
|
||||
. 'require ' . var_export($root . '/lib/Cloak/Pipeline/CheckPipeline.php', true) . ';'
|
||||
. '$_SESSION=[];'
|
||||
. 'CloakJudgmentCache::storeFromByApi(["ip"=>"1.1.1.1","country"=>"US","result"=>"true","reason"=>""]);'
|
||||
. 'echo CheckPipeline::resolveClientCacheFastPath() ? "1" : "0";'
|
||||
);
|
||||
$zpCacheCmd = escapeshellarg(PHP_BINARY) . ' -r ' . escapeshellarg(
|
||||
'define("SHOW_SITE_MODE_SWITCH","zp");'
|
||||
. 'define("CLOAK_RISK_NUMBER",0);'
|
||||
. 'require ' . var_export($root . '/lib/Cloak/CloakJudgmentCache.php', true) . ';'
|
||||
. 'require ' . var_export($root . '/lib/Cloak/Pipeline/CheckPipeline.php', true) . ';'
|
||||
. '$_SESSION=[];'
|
||||
. 'CloakJudgmentCache::storeFromByApi(["ip"=>"1.1.1.1","country"=>"US","result"=>"true","reason"=>""]);'
|
||||
. 'echo (CheckPipeline::resolveZpFastPath() && !CheckPipeline::resolveClientCacheFastPath()) ? "1" : "0";'
|
||||
);
|
||||
$tests['zp_before_cache'] = trim((string) shell_exec($zpCacheCmd)) === '1';
|
||||
$tests['fp_mode_fast'] = trim((string) shell_exec($fpCmd)) === '1';
|
||||
$tests['cache_on_ip_check'] = trim((string) shell_exec($cacheCmd)) === '1';
|
||||
$tests['zp_mode_fast'] = trim((string) shell_exec($zpCmd)) === '1';
|
||||
|
||||
$fpNoRiskCmd = escapeshellarg(PHP_BINARY) . ' -r ' . escapeshellarg(
|
||||
'define("SHOW_SITE_MODE_SWITCH","fp");'
|
||||
. 'define("CLOAK_RISK_NUMBER",51);'
|
||||
. 'require ' . var_export($root . '/lib/Cloak/RiskSecondaryGate.php', true) . ';'
|
||||
. 'echo RiskSecondaryGate::isEnabled() && !RiskSecondaryGate::isEnabledForRequest() ? "1" : "0";'
|
||||
);
|
||||
$tests['fp_mode_skips_secondary_risk'] = trim((string) shell_exec($fpNoRiskCmd)) === '1';
|
||||
|
||||
$ok = !in_array(false, $tests, true);
|
||||
echo json_encode(['ok' => $ok, 'tests' => $tests], JSON_UNESCAPED_UNICODE) . "\n";
|
||||
exit($ok ? 0 : 1);
|
||||
Regular → Executable
+53
-26
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* 二次风控 Session 缓存回归(CLI 输出 JSON)
|
||||
* CloakJudgmentCache / RiskSecondaryCache 回归(CLI JSON)
|
||||
*/
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
exit(1);
|
||||
@@ -9,41 +9,69 @@ if (PHP_SAPI !== 'cli') {
|
||||
|
||||
$root = dirname(__DIR__);
|
||||
require_once $root . '/cong.php';
|
||||
require_once $root . '/lib/CloakHttpHelpers.php';
|
||||
require_once $root . '/lib/Cloak/ClientIpResolver.php';
|
||||
require_once $root . '/lib/Cloak/RiskSecondaryGate.php';
|
||||
require_once $root . '/lib/Cloak/CloakJudgmentCache.php';
|
||||
require_once $root . '/lib/Cloak/RiskSecondaryCache.php';
|
||||
|
||||
if (!defined('CLOAK_RISK_NUMBER')) {
|
||||
define('CLOAK_RISK_NUMBER', 51);
|
||||
}
|
||||
if (!defined('COSTM_IP_SCORE')) {
|
||||
define('COSTM_IP_SCORE', 'test_campaign');
|
||||
}
|
||||
|
||||
$_SESSION = [];
|
||||
$tests = [];
|
||||
|
||||
$tests = [];
|
||||
|
||||
RiskSecondaryCache::store([
|
||||
'ip' => '203.0.113.10',
|
||||
'result' => 'true',
|
||||
'reason' => 'ok',
|
||||
'fp_url' => 'https://fp.example/a',
|
||||
CloakJudgmentCache::storeFromByApiRisk([
|
||||
'ip' => '203.0.113.10',
|
||||
'country' => 'US',
|
||||
'result' => 'true',
|
||||
'reason' => '',
|
||||
'fp_url' => 'https://fp.example/a',
|
||||
]);
|
||||
$hit = RiskSecondaryCache::get('203.0.113.10');
|
||||
$tests['same_ip_hit'] = is_array($hit) && ($hit['result'] ?? '') === 'true';
|
||||
$hit = CloakJudgmentCache::getFinal('203.0.113.10');
|
||||
$tests['same_ip_final_hit'] = is_array($hit) && ($hit['result'] ?? '') === 'true' && ($hit['stage'] ?? '') === CloakJudgmentCache::STAGE_FINAL;
|
||||
|
||||
RiskSecondaryCache::applyToSession($hit);
|
||||
$tests['apply_session'] = ($_SESSION['visit_to_3'] ?? '') == 3 && ($_SESSION['check_result'] ?? '') === 'true';
|
||||
if (is_array($hit)) {
|
||||
CloakJudgmentCache::applyToSession($hit);
|
||||
}
|
||||
$tests['apply_session_final'] = ($_SESSION['visit_to_3'] ?? '') == 3 && ($_SESSION['check_result'] ?? '') === 'true';
|
||||
|
||||
$miss = RiskSecondaryCache::get('198.51.100.1');
|
||||
$tests['ip_change_miss'] = $miss === null && empty($_SESSION[RiskSecondaryCache::SESSION_KEY]);
|
||||
$tests['ip_change_resets_visit_to_3'] = ($_SESSION['visit_to_3'] ?? '') === '1';
|
||||
$hitNewIp = CloakJudgmentCache::get('198.51.100.5');
|
||||
$tests['ip_change_still_valid'] = is_array($hitNewIp) && ($hitNewIp['result'] ?? '') === 'true';
|
||||
$tests['ip_change_updates_ip_field'] = ($hitNewIp['ip'] ?? '') === '198.51.100.5';
|
||||
$tests['ip_change_keeps_session_key'] = !empty($_SESSION[CloakJudgmentCache::SESSION_KEY]);
|
||||
|
||||
RiskSecondaryCache::store([
|
||||
'ip' => '203.0.113.10',
|
||||
'result' => 'false',
|
||||
'reason' => 'deny',
|
||||
'fp_url' => 'https://zp.example/',
|
||||
$partialOnly = CloakJudgmentCache::getFinal('198.51.100.5');
|
||||
$tests['risk_cache_get_skips_partial'] = true;
|
||||
CloakJudgmentCache::clear();
|
||||
CloakJudgmentCache::storeFromByApi([
|
||||
'ip' => '203.0.113.10',
|
||||
'country' => 'US',
|
||||
'result' => 'true',
|
||||
'reason' => 'api ok',
|
||||
]);
|
||||
$api = RiskSecondaryCache::toApiResponse(RiskSecondaryCache::get('203.0.113.10'));
|
||||
$tests['to_api_response'] = $api['result'] === false && $api['reason'] === RiskSecondaryCache::hitReason();
|
||||
$tests['byapi_stage_is_partial'] = CloakJudgmentCache::isPartial();
|
||||
$tests['risk_cache_get_skips_partial'] = RiskSecondaryCache::get('203.0.113.10') === null;
|
||||
|
||||
RiskSecondaryCache::clear();
|
||||
$tests['clear'] = RiskSecondaryCache::get('203.0.113.10') === null;
|
||||
CloakJudgmentCache::storeFromByApiRisk([
|
||||
'ip' => '203.0.113.10',
|
||||
'country' => 'US',
|
||||
'result' => 'false',
|
||||
'reason' => 'deny',
|
||||
'fp_url' => 'https://zp.example/',
|
||||
]);
|
||||
$apiHit = CloakJudgmentCache::getFinal('203.0.113.10');
|
||||
$api = is_array($apiHit) ? CloakJudgmentCache::toApiResponse($apiHit) : ['result' => true, 'reason' => ''];
|
||||
$tests['to_api_response'] = $api['result'] === false && $api['reason'] === CloakJudgmentCache::hitReason();
|
||||
|
||||
$_SESSION[CloakJudgmentCache::SESSION_KEY]['risk_number'] = -1;
|
||||
$tests['risk_number_change_invalidates'] = CloakJudgmentCache::getFinal('203.0.113.10') === null;
|
||||
|
||||
CloakJudgmentCache::clear();
|
||||
$tests['clear'] = !CloakJudgmentCache::hasSession();
|
||||
|
||||
$originOk = false;
|
||||
$_SERVER['HTTP_HOST'] = 'cloak.example.com';
|
||||
@@ -59,6 +87,5 @@ $badOrigin = !(bool) $method->invoke(null, 'https://evil.other.com');
|
||||
$tests['cors_reject_foreign'] = $badOrigin;
|
||||
|
||||
$ok = !in_array(false, $tests, true);
|
||||
|
||||
echo json_encode(['ok' => $ok, 'tests' => $tests], JSON_UNESCAPED_UNICODE) . "\n";
|
||||
exit($ok ? 0 : 1);
|
||||
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* 二次风控 Session 与 visit 日志防重复写库
|
||||
*/
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$root = dirname(__DIR__);
|
||||
require_once $root . '/cong.php';
|
||||
require_once $root . '/lib/Cloak/VisitorVisitContext.php';
|
||||
require_once $root . '/lib/Cloak/RiskSecondarySession.php';
|
||||
|
||||
$_SESSION = [];
|
||||
|
||||
RiskSecondarySession::markWaitLog(42);
|
||||
$tests = [];
|
||||
$tests['wait_binds_visit_log'] = VisitorVisitContext::currentLogId() === 42;
|
||||
$tests['wait_should_update'] = VisitorVisitContext::shouldPersistAsUpdate();
|
||||
|
||||
$_SESSION['visit_to_3'] = 3;
|
||||
VisitorVisitContext::finalizeVisit('true');
|
||||
$tests['skip_fp_after_fcheck'] = RiskSecondarySession::shouldSkipFpPageLog();
|
||||
|
||||
RiskSecondarySession::clear();
|
||||
VisitorVisitContext::clear();
|
||||
$tests['clear_resets'] = VisitorVisitContext::currentLogId() === 0;
|
||||
|
||||
$ok = !in_array(false, $tests, true);
|
||||
echo json_encode(['ok' => $ok, 'tests' => $tests], JSON_UNESCAPED_UNICODE) . "\n";
|
||||
exit($ok ? 0 : 1);
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* 子进程:SimulationRouteResolver 在 zp + 白名单时应走真实页
|
||||
*/
|
||||
$root = dirname(__DIR__);
|
||||
$_SERVER['PHP_SELF'] = '/index.php';
|
||||
$_SERVER['HTTP_HOST'] = 'test.local';
|
||||
$_SERVER['REMOTE_ADDR'] = '8.8.8.8';
|
||||
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0';
|
||||
$_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'en-US';
|
||||
$_SERVER['SERVER_PORT'] = 443;
|
||||
$_SERVER['HTTPS'] = 'on';
|
||||
$_GET = [];
|
||||
|
||||
require_once $root . '/cong.php';
|
||||
session_start();
|
||||
$_SESSION = [
|
||||
'cloak_whitelist_fast' => true,
|
||||
'check_result' => 'true',
|
||||
'visit_to_3' => '3',
|
||||
];
|
||||
|
||||
include $root . '/tools/fixtures/regression_zp_whitelist.php';
|
||||
require_once $root . '/lib/bootstrap.php';
|
||||
require_once $root . '/lib/Cloak/SimulationRouteResolver.php';
|
||||
|
||||
$v_info = new visitorInfo();
|
||||
$v_info->get_visitor_Info(COSTM_IP_SCORE, CHECK_KEY, SHOW_SITE_COUNTRY);
|
||||
$logs = [
|
||||
'site_name' => 'test.local',
|
||||
'customers_ip' => $v_info->v_ip,
|
||||
'country' => 'US',
|
||||
'result' => 'true',
|
||||
'reason' => '白名单',
|
||||
];
|
||||
$sim = SimulationRouteResolver::dispatch([
|
||||
'v_info' => $v_info,
|
||||
'logs' => $logs,
|
||||
'config_name' => 'index',
|
||||
'reason' => '白名单',
|
||||
'model' => 'PC',
|
||||
]);
|
||||
|
||||
echo json_encode([
|
||||
'ok' => ($sim['branch'] ?? '') === 'fp_page' && ($sim['needs_secondary'] ?? true) === false,
|
||||
'sim' => $sim,
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
Executable
+72
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* Visit 生命周期与 reason 规范化回归(CLI JSON)
|
||||
*/
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$root = dirname(__DIR__);
|
||||
require_once $root . '/cong.php';
|
||||
require_once $root . '/lib/Cloak/ReasonHelper.php';
|
||||
require_once $root . '/lib/Cloak/VisitorVisitContext.php';
|
||||
require_once $root . '/lib/Cloak/RiskSecondarySession.php';
|
||||
require_once $root . '/lib/Cloak/CloakJudgmentCache.php';
|
||||
require_once $root . '/lib/Cloak/RiskSecondaryCache.php';
|
||||
|
||||
$tests = [];
|
||||
|
||||
// reason 规范化
|
||||
$tests['true_reason_empty'] = cloak_normalize_log_reason('true', '二次风控缓存命中') === '';
|
||||
$tests['cache_false_reason'] = cloak_cache_hit_log_reason('false') === '缓存';
|
||||
$tests['cache_hit_reason'] = CloakJudgmentCache::hitReason() === '缓存';
|
||||
$tests['false_reason_required'] = cloak_normalize_log_reason('false', '') !== '';
|
||||
$tests['wait_default_reason'] = cloak_normalize_log_reason('wait', '') === '二次风控检测中';
|
||||
$tests['finalize_true_empty'] = cloak_finalize_reason('缓存', 'true') === '';
|
||||
|
||||
// 新 visit / 续步判定
|
||||
$_SESSION = [];
|
||||
$_SERVER['SCRIPT_NAME'] = '/ip_check.php';
|
||||
unset($_GET['time'], $_SERVER['HTTP_SEC_FETCH_MODE']);
|
||||
$tests['first_load_new_visit'] = VisitorVisitContext::isNewVisit() && !VisitorVisitContext::isContinuation();
|
||||
|
||||
VisitorVisitContext::bindLogId(1001);
|
||||
VisitorVisitContext::markVisitActive();
|
||||
$tests['wait_bound_not_new'] = !VisitorVisitContext::isNewVisit() && VisitorVisitContext::shouldPersistAsUpdate();
|
||||
|
||||
$_GET['time'] = '123';
|
||||
$tests['time_param_continuation'] = VisitorVisitContext::isContinuation();
|
||||
unset($_GET['time']);
|
||||
|
||||
$_SERVER['HTTP_SEC_FETCH_MODE'] = 'navigate';
|
||||
VisitorVisitContext::evaluateAtEntry();
|
||||
$tests['refresh_clears_visit'] = VisitorVisitContext::currentLogId() === 0 && VisitorVisitContext::isNewVisit();
|
||||
unset($_SERVER['HTTP_SEC_FETCH_MODE']);
|
||||
|
||||
// f_check 续步
|
||||
$_SESSION = [];
|
||||
VisitorVisitContext::bindLogId(2002);
|
||||
$_SERVER['SCRIPT_NAME'] = '/f_check.php';
|
||||
$tests['fcheck_is_continuation'] = VisitorVisitContext::isContinuation();
|
||||
$_SERVER['SCRIPT_NAME'] = '/ip_check.php';
|
||||
|
||||
// finalize 后新 visit
|
||||
VisitorVisitContext::finalizeVisit('true');
|
||||
$tests['after_finalize_new_visit'] = VisitorVisitContext::isNewVisit();
|
||||
|
||||
// RiskSecondarySession skip 写库
|
||||
$_SESSION['visit_to_3'] = 3;
|
||||
VisitorVisitContext::bindLogId(3003);
|
||||
VisitorVisitContext::finalizeVisit('true');
|
||||
$tests['skip_fp_after_finalize'] = RiskSecondarySession::shouldSkipFpPageLog();
|
||||
|
||||
// 缓存命中 reason 不落库为 true 文案
|
||||
$cached = ['result' => 'true', 'reason' => 'ok', 'fp_url' => 'https://fp/a'];
|
||||
$api = RiskSecondaryCache::toApiResponse($cached);
|
||||
$normalized = cloak_normalize_log_reason($api['result'] ? 'true' : 'false', $api['reason']);
|
||||
$tests['cache_hit_true_reason_empty'] = $normalized === '';
|
||||
|
||||
$ok = !in_array(false, $tests, true);
|
||||
echo json_encode(['ok' => $ok, 'tests' => $tests], JSON_UNESCAPED_UNICODE) . "\n";
|
||||
exit($ok ? 0 : 1);
|
||||
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* 二次风控 wait 日志:同步完整落库 + f_check UPDATE 不覆盖首段字段
|
||||
*/
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$root = dirname(__DIR__);
|
||||
require_once $root . '/cong.php';
|
||||
require_once $root . '/lib/Cloak/VisitorApiAudit.php';
|
||||
require_once $root . '/lib/Cloak/VisitorVisitContext.php';
|
||||
require_once $root . '/lib/Cloak/VisitorRepository.php';
|
||||
require_once $root . '/lib/Cloak/VisitorLogWorker.php';
|
||||
require_once $root . '/lib/Cloak/FCheckHandler.php';
|
||||
require_once $root . '/lib/Cloak/PipelineTimer.php';
|
||||
|
||||
$tests = [];
|
||||
|
||||
// wait 路径应走 insertFull(源码约定)
|
||||
$repoSrc = file_get_contents($root . '/lib/Cloak/VisitorRepository.php');
|
||||
$tests['wait_uses_sync_full'] = strpos($repoSrc, 'cloak_write_log_db_wait_sync') !== false
|
||||
&& strpos($repoSrc, "if (\$result === 'wait')") !== false
|
||||
&& strpos($repoSrc, 'insertMinimal($logs)') === false;
|
||||
|
||||
$_SESSION = [];
|
||||
$_SERVER['HTTP_USER_AGENT'] = 'VerifyWaitUA/1.0';
|
||||
$_SERVER['HTTP_REFERER'] = 'https://referer.example/ads';
|
||||
$_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'en-US,en;q=0.9';
|
||||
$GLOBALS['__cloak_judge_timing'] = '{"total_ms":12.5,"stages":[{"name":"API","ms":8}]}';
|
||||
VisitorApiAudit::recordByApiRequest(['id' => 'camp', 'ip' => '203.0.113.9']);
|
||||
VisitorApiAudit::recordByApiResponse(['result' => true, 'reason' => '']);
|
||||
|
||||
$waitLogs = [
|
||||
'campagin_id' => 'wait_verify',
|
||||
'visit_md5_code' => 'wait_' . substr(md5((string) microtime(true)), 0, 12),
|
||||
'site_name' => 'wait.test',
|
||||
'customers_ip' => '203.0.113.9',
|
||||
'country' => 'US',
|
||||
'result' => 'wait',
|
||||
'reason' => '二次风控检测中',
|
||||
'v_referer' => 'https://referer.example/ads',
|
||||
'Client' => 'PC',
|
||||
'v_Browser' => 'chrome',
|
||||
'v_PageURL' => 'https://wait.test/landing?utm=1',
|
||||
'accept_language' => 'English',
|
||||
'fp_url' => '',
|
||||
'device' => 'PC',
|
||||
];
|
||||
$GLOBALS['__cloak_force_sync_log'] = true;
|
||||
$waitId = write_log_db($waitLogs);
|
||||
unset($GLOBALS['__cloak_force_sync_log']);
|
||||
|
||||
$tests['wait_insert_returns_id'] = $waitId !== null && (int) $waitId > 0;
|
||||
|
||||
if ($waitId) {
|
||||
$conn = @new mysqli('localhost', DB_USERNAME, DB_PASSWORD, DB_NAME);
|
||||
if ($conn && !$conn->connect_error) {
|
||||
$res = $conn->query('SELECT `page`, `user_agent`, `http_referer`, `accept_language_raw`, `judge_timing`, `api_by_request`, `api_by_response`, `result` FROM `visitor_logs` WHERE `id`=' . (int) $waitId . ' LIMIT 1');
|
||||
$row = $res ? $res->fetch_assoc() : null;
|
||||
if ($row) {
|
||||
$tests['wait_has_page'] = trim((string) $row['page']) !== '';
|
||||
$tests['wait_has_user_agent'] = trim((string) $row['user_agent']) !== '';
|
||||
$tests['wait_has_referer'] = trim((string) $row['http_referer']) !== '';
|
||||
$tests['wait_has_timing'] = trim((string) $row['judge_timing']) !== '';
|
||||
$tests['wait_has_api_by_req'] = trim((string) $row['api_by_request']) !== '';
|
||||
$tests['wait_has_api_by_resp'] = trim((string) $row['api_by_response']) !== '';
|
||||
$tests['wait_result_is_wait'] = ($row['result'] ?? '') === 'wait';
|
||||
}
|
||||
|
||||
VisitorVisitContext::bindLogId((int) $waitId);
|
||||
FCheckHandler::updateLog((int) $waitId, [
|
||||
'result' => 'true',
|
||||
'reason' => '',
|
||||
'fp_url' => 'https://fp.example/page',
|
||||
], ['ip' => '203.0.113.9'], ['id' => 'camp'], ['result' => true], true);
|
||||
|
||||
$res2 = $conn->query('SELECT `page`, `user_agent`, `judge_timing`, `api_by_request`, `result`, `fp_url` FROM `visitor_logs` WHERE `id`=' . (int) $waitId . ' LIMIT 1');
|
||||
$row2 = $res2 ? $res2->fetch_assoc() : null;
|
||||
if ($row2) {
|
||||
$tests['after_fcheck_keeps_page'] = trim((string) $row2['page']) === trim((string) $row['page']);
|
||||
$tests['after_fcheck_keeps_user_agent'] = trim((string) $row2['user_agent']) === trim((string) $row['user_agent']);
|
||||
$tests['after_fcheck_keeps_timing'] = trim((string) $row2['judge_timing']) === trim((string) $row['judge_timing']);
|
||||
$tests['after_fcheck_keeps_api_by'] = trim((string) $row2['api_by_request']) === trim((string) $row['api_by_request']);
|
||||
$tests['after_fcheck_updates_result'] = ($row2['result'] ?? '') === 'true';
|
||||
$tests['after_fcheck_updates_fp_url'] = strpos((string) $row2['fp_url'], 'fp.example') !== false;
|
||||
}
|
||||
|
||||
$conn->query('DELETE FROM `visitor_logs` WHERE `id`=' . (int) $waitId);
|
||||
$conn->close();
|
||||
}
|
||||
}
|
||||
|
||||
$ok = !in_array(false, $tests, true);
|
||||
echo json_encode(['ok' => $ok, 'tests' => $tests], JSON_UNESCAPED_UNICODE) . "\n";
|
||||
exit($ok ? 0 : 1);
|
||||
Reference in New Issue
Block a user