Browse Source

refactor: new ICP query model

dev
Dnomd343 3 years ago
parent
commit
8bad496975
  1. 1
      .env.example
  2. 40
      functions/Domain.php
  3. 208
      models/icpQuery.php

1
.env.example

@ -20,7 +20,6 @@ KMS_VLMCS=/usr/bin/vlmcs
# ChinaZ API
ICP_KEY=
ICP_API=https://apidatav2.chinaz.com/single/icp
# CFOP Pic
CFOP_GAN=BQACAgUAAxkBAAIBtGEOLnr4Q6D4Z_80bgfXq5xsZMeWAAKtAwACWy55VOU-SGKqc7aMIAQ

40
functions/Domain.php

@ -1,6 +1,8 @@
<?php
class Domain { // 域名相关功能
private $tldDB = './db/tldInfo.db'; // 顶级域名数据库
public function isDomain($domain) { // 检测是否为域名
preg_match('/^(?=^.{3,255}$)[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+$/', $domain, $match);
return (count($match) != 0);
@ -16,12 +18,8 @@ class Domain { // 域名相关功能
}
return false;
}
}
class extractDomain {
private $tldDB = './db/tldInfo.db'; // 顶级域名数据库
private function getAllTlds() { // 获取所有顶级域 含次级域
private function getTldList() { // 获取所有顶级域 含次级域
$db = new SqliteDB($this->tldDB);
$res = $db->query('SELECT record FROM `list`;');
while ($row = $res->fetchArray(SQLITE3_ASSOC)) {
@ -30,28 +28,21 @@ class extractDomain {
return $tlds; // Unicode字符使用Punycode编码
}
private function isDomain($domain) { // 检测是否为域名
preg_match('/^(?=^.{3,255}$)[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+$/', $domain, $match);
return (count($match) != 0);
}
private function getDomain($url) { // 从URL获取域名
private function extractDomain($url) { // 从URL获取域名
$url = preg_replace('/^[\w]+:\/\//', '', $url); // 去除协议字段
$url = explode('?', $url)[0]; // 去除请求参数内容
$domain = explode('/', $url)[0]; // 分离域名
return (new Punycode)->encode($domain);
}
private function getTld($domain) { // 搜索域名TLD
$tlds = $this->getAllTlds(); // 获取TLD列表
private function getTld($domain) { // 匹配域名TLD
$tlds = $this->getTldList(); // 获取TLD列表
foreach ($tlds as $tld) {
if (substr($domain, -strlen($tld)) === $tld) { // 匹配测试
$target[] = $tld;
}
}
if (count($target) === 0) {
return ''; // 匹配不到TLD
};
if (!isset($target)) { return null; } // 匹配不到TLD
$type = 0;
foreach ($target as $tld) { // 遍历可能的结果
$num = substr_count($tld, '.');
@ -70,15 +61,13 @@ class extractDomain {
}
public function analyse($url) { // 分析域名信息
$domain = $this->getDomain($url);
$domain = $this->extractDomain($url);
if (!$this->isDomain($domain)) { // 域名不合格
return array();
}
$tld = $this->getTld($domain);
if ($tld == '') { // 匹配不到TLD
return array(
'domain' => $domain
);
if ($tld === null) { // 匹配不到TLD
return [ 'domain' => $domain ];
}
return array(
'domain' => $domain,
@ -86,6 +75,15 @@ class extractDomain {
'site' => $this->getSite($domain, $tld)
);
}
public function icpTldInfo($tld) { // 查询TLD的ICP信息
$db = new SqliteDB($this->tldDB);
$info = $db->query('SELECT * FROM `icp` WHERE tld="' . $tld . '";');
$info = $info->fetchArray(SQLITE3_ASSOC);
if ($info == '') { return null; } // TLD不存在于ICP列表中
$info['site'] = json_decode(base64_decode($info['site']), true);
return $info;
}
}
?>

208
models/icpQuery.php

@ -1,161 +1,56 @@
<?php
class icpQuery {
class icpQuery { // ICP备案查询
private $apiPath;
public function __construct() {
global $env;
$this->apiPath = $env['ICP_API'] . '?key=' . $env['ICP_KEY'] . '&domain=';
$this->apiPath = 'https://apidatav2.chinaz.com/single/icp?key=' . $GLOBALS['env']['ICP_KEY'] . '&domain=';
}
private function getIcpInfo($domain) { // ICP备案查询
$domain = urlencode((new Punycode)->decode($domain));
$info = json_decode(file_get_contents($this->apiPath . $domain), true);
if ($info['StateCode'] === 1) { // 存在ICP备案
$info = array(
'status' => 'ok',
$domain = urlencode((new Punycode)->decode($domain)); // API接口需要URL编码原始域名
$info = json_decode(file_get_contents($this->apiPath . $domain), true); // 请求API接口
if ($info['StateCode'] === 1) {
return $info['Result'] + array( // 存在ICP备案
'time' => time(),
'hasIcp' => true
) + $info['Result'];
} else if ($info['StateCode'] === 0) { // 无ICP备案
if ($info['Reason'] !== '暂无备案信息') {
return array(
'status' => 'error',
'message' => $info['Reason']
);
}
$info = array(
'status' => 'ok',
'hasIcp' => false,
'icpMsg' => $info['Reason']
);
} else {
$info = array(
'status' => 'error', // 服务错误
'message' => 'Server error'
} else if ($info['StateCode'] === 0) {
if ($info['Reason'] !== '暂无备案信息') { return null; } // 服务错误
return array( // 无ICP备案
'time' => time(),
'hasIcp' => false
);
} else {
return null; // 服务错误
}
return $info;
}
public function isCache($domain) { // 查询域名是否存在缓存
$redis = new redisCache('icp');
$redis = new RedisCache('icp');
$info = $redis->getData($domain); // 查询缓存数据
return ($info) ? true : false;
}
public function icpInfo($domain) { // ICP查询入口 带缓存
$redis = new redisCache('icp');
public function icpInfo($domain, $isCache = true) { // ICP查询入口 默认带缓存
$redis = new RedisCache('icp');
$info = $redis->getData($domain); // 查询缓存数据
if (!$info) { // 缓存未命中
$info = $this->getIcpInfo($domain); // 执行查询
if ($info['status'] !== 'ok') { // 查询错误
return $info;
}
unset($info['status']);
$redis->setData($domain, json_encode($info), 90 * 86400); // 缓存90day
if (!$isCache || !$info) { // 不缓存 或 缓存未命中
$info = $this->getIcpInfo($domain); // 发起查询
if ($info === null) { return null; } // 服务错误
$redis->setData($domain, json_encode($info)); // 缓存ICP信息 永久
} else { // 缓存命中
$info = json_decode($info, true); // 使用缓存数据
}
return array(
'status' => 'ok'
) + $info;
return $info;
}
}
class icpQueryEntry {
private function getIcpTlds() { // 获取所有可ICP备案的顶级域
$db = new SqliteDB('./db/tldInfo.db');
$punycode = new Punycode();
$res = $db->query('SELECT tld FROM `icp`;');
while ($row = $res->fetchArray(SQLITE3_ASSOC)) {
$tlds[] = $punycode->encode($row['tld']); // 转为Punycode编码
}
return $tlds; // Unicode字符使用Punycode编码
}
private function isIcpEnable($tld) { // 检查TLD是否允许ICP备案
$icpTlds = $this->getIcpTlds();
foreach ($icpTlds as $icpTld) { // 遍历所有可ICP域名
if ($icpTld === $tld) {
return true; // 允许备案
}
}
return false; // 无法备案
}
private function check($str) { // 检查输入参数
$content = (new extractDomain)->analyse($str);
if (!isset($content['domain'])) { // 格式错误
return array(
'status' => 'error',
'message' => 'Illegal Request'
);
}
if (!isset($content['tld'])) { // 未知TLD
return array(
'status' => 'error',
'message' => 'Unknow TLD'
);
}
if (!$this->isIcpEnable($content['tld'])) {
return array(
'status' => 'error',
'message' => '`' . $content['tld'] . '` is not allowed in ICP'
);
}
return array(
'status' => 'ok',
'domain' => $content['site'] // 返回主域名
);
}
public function query($rawParam) { // ICP备案查询入口
if ($rawParam == '' || $rawParam === 'help') { // 显示使用说明
tgApi::sendMessage(array(
'parse_mode' => 'Markdown',
'text' => '*Usage:* `/icp domain`',
));
return;
}
$content = $this->check($rawParam);
if ($content['status'] !== 'ok') { // 请求参数错误
tgApi::sendMarkdown($content['message']);
return;
}
$isCache = true;
$domain = $content['domain'];
class icpQueryEntry { // ICP信息查询入口
private function genMessage($domain, $info) { // 生成ICP数据消息
if ($info === null) { return 'Server error'; } // 服务错误
$msg = '`' . (new Punycode)->decode($domain) . '`' . PHP_EOL;
if (!(new icpQuery)->isCache($domain)) { // 域名信息未缓存
$message = tgApi::sendMarkdown($msg . 'ICP备案信息查询中...');
$message = json_decode($message, true);
$isCache = false;
}
$info = (new icpQuery)->icpInfo($domain); // 发起查询
if ($info['status'] !== 'ok') {
if ($isCache) { // 没有缓冲信息 直接发送
tgApi::sendText($info['message']); // 查询出错
} else {
tgApi::editMessage(array(
'text' => $info['message'],
'message_id' => $message['result']['message_id']
));
}
return;
}
if (!$info['hasIcp']) { // 没有ICP备案
$content = array(
'parse_mode' => 'Markdown',
'text' => $msg . $info['icpMsg']
);
if ($isCache) { // 没有缓冲信息 直接发送
tgApi::sendMessage($content);
} else {
tgApi::editMessage(array(
'message_id' => $message['result']['message_id']
) + $content);
}
return;
}
if (!$info['hasIcp']) { return $msg . '暂无备案信息'; } // 无ICP备案
$msg .= '*类型:*' . $info['CompanyType'] . PHP_EOL;
if ($info['Owner'] != '') { // 负责人为空不显示
$msg .= '*负责人:*' . $info['Owner'] . PHP_EOL;
@ -172,16 +67,53 @@ class icpQueryEntry {
$msg .= '*网站名:*' . $info['SiteName'] . PHP_EOL;
$msg .= '*审核时间:*' . $info['VerifyTime'] . PHP_EOL;
$msg .= '*许可证号:*' . $info['SiteLicense'] . PHP_EOL;
if ($isCache) { // 没有缓冲信息 直接发送
tgApi::sendMarkdown($msg); // 返回查询数据
} else {
tgApi::editMessage(array( // 返回查询数据 修改原消息
return $msg;
}
private function sendIcpInfo($domain) { // 查询并发送ICP备案信息
if (!(new icpQuery)->isCache($domain)) { // 未缓存
$headerMsg = '`' . (new Punycode)->decode($domain) . '`' . PHP_EOL;
$message = tgApi::sendMarkdown($headerMsg . 'ICP备案信息查询中...'); // 发送缓冲信息
$messageId = json_decode($message, true)['result']['message_id'];
$info = (new icpQuery)->icpInfo($domain); // 发起查询
tgApi::editMessage(array(
'parse_mode' => 'Markdown',
'text' => $msg,
'message_id' => $message['result']['message_id']
'message_id' => $messageId, // 替换原消息
'text' => $this->genMessage($domain, $info)
));
} else { // 已缓存
$info = (new icpQuery)->icpInfo($domain); // 获取缓存信息
$message = tgApi::sendMarkdown($this->genMessage($domain, $info)); // 先输出
if (time() - $info['time'] < 90 * 86400) { return; } // 缓存有效期90day
$infoRenew = (new icpQuery)->icpInfo($domain, false); // 不带缓存查询
$messageId = json_decode($message, true)['result']['message_id'];
unset($info['time']);
unset($infoRenew['time']);
if ($info !== $infoRenew) { // 数据出现变化
tgApi::editMessage(array(
'parse_mode' => 'Markdown',
'message_id' => $messageId,
'text' => $this->genMessage($domain, $infoRenew) // 更新信息
));
}
}
}
public function query($rawParam) { // ICP备案查询入口
if ($rawParam == '' || $rawParam === 'help') {
tgApi::sendMarkdown('*Usage:* `/icp domain`'); // 显示使用说明
return;
}
$content = (new Domain)->analyse($rawParam);
if (!isset($content['domain'])) { // 格式错误
tgApi::sendText('Illegal Request');
} else if (!isset($content['tld'])) { // 未知TLD
tgApi::sendText('Unknow TLD');
} else if ((new Domain)->icpTldInfo($content['tld']) === null) { // TLD无法ICP备案
tgApi::sendMarkdown('`' . $content['tld'] . '` is not allowed in ICP');
} else {
$this->sendIcpInfo($content['site']); // 查询并输出域名备案信息
}
}
}

Loading…
Cancel
Save