fix(ip-geo): fallback free lookup when Amap key platform mismatches
This commit is contained in:
@@ -134,31 +134,71 @@ class IPGeo {
|
||||
case 'qq':
|
||||
return $this->query_qq($ip, $config);
|
||||
case 'amap':
|
||||
return $this->query_amap($ip, $config);
|
||||
$amap = $this->query_amap($ip, $config);
|
||||
if ($this->has_location($amap)) {
|
||||
return $amap;
|
||||
}
|
||||
// Credential / platform mismatch: free path so front still works.
|
||||
if ($this->should_fallback_free($amap)) {
|
||||
$free = $this->query_pconline($ip);
|
||||
if ($this->has_location($free)) {
|
||||
$free['detail'] = 'amap_failed_fallback_free:' . (string) ($amap['detail'] ?? $amap['reason'] ?? '');
|
||||
return $free;
|
||||
}
|
||||
}
|
||||
return $amap;
|
||||
case 'polling':
|
||||
$last = $this->empty_result('provider_empty');
|
||||
foreach (['qq', 'amap', 'null'] as $fallback) {
|
||||
// Skip providers that clearly lack keys.
|
||||
if ($fallback === 'qq' && empty($config['ip_addr_sdk_qq_appkey'])) {
|
||||
continue;
|
||||
}
|
||||
if ($fallback === 'amap' && empty($config['ip_addr_sdk_amap_appkey'])) {
|
||||
continue;
|
||||
}
|
||||
$result = $this->query_provider($fallback, $ip, $config);
|
||||
// Avoid re-entering amap→free→… recursion: call leaf methods.
|
||||
if ($fallback === 'amap') {
|
||||
$result = $this->query_amap($ip, $config);
|
||||
} elseif ($fallback === 'qq') {
|
||||
$result = $this->query_qq($ip, $config);
|
||||
} else {
|
||||
$result = $this->query_pconline($ip);
|
||||
}
|
||||
if ($this->has_location($result)) {
|
||||
return $result;
|
||||
}
|
||||
$last = $result;
|
||||
}
|
||||
return $last;
|
||||
// Last resort free path.
|
||||
$free = $this->query_pconline($ip);
|
||||
return $this->has_location($free) ? $free : $last;
|
||||
case 'null':
|
||||
default:
|
||||
// Canonical free provider: 太平洋 (pconline). Label matches admin UI.
|
||||
// Admin label「太平洋公共接口」: pconline, with ip-api if blocked.
|
||||
return $this->query_pconline($ip);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a paid-provider failure should fall back to free IP lookup.
|
||||
*/
|
||||
private function should_fallback_free(array $result): bool {
|
||||
$reason = (string) ($result['reason'] ?? '');
|
||||
if (in_array($reason, ['missing_key', 'http_error'], true)) {
|
||||
return true;
|
||||
}
|
||||
if ($reason !== 'provider_error') {
|
||||
return false;
|
||||
}
|
||||
$detail = strtoupper((string) ($result['detail'] ?? ''));
|
||||
foreach (['USERKEY_PLAT_NOMATCH', 'INVALID_USER_KEY', 'INVALID_USER_SCODE', 'DAILY_QUERY_OVER_LIMIT', 'ACCESS_TOO_FREQUENT', 'CUQPS_HAS_EXCEEDED_THE_LIMIT'] as $code) {
|
||||
if (str_contains($detail, $code)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function query_qq(string $ip, array $config): array {
|
||||
$appkey = trim((string) ($config['ip_addr_sdk_qq_appkey'] ?? ''));
|
||||
$secretkey = trim((string) ($config['ip_addr_sdk_qq_secretkey'] ?? ''));
|
||||
|
||||
Reference in New Issue
Block a user