From 8bad49697512ef74b633aaf27c7c79e58c604968 Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sun, 22 Aug 2021 01:18:05 +0800 Subject: [PATCH] refactor: new ICP query model --- .env.example | 1 - functions/Domain.php | 40 ++++----- models/icpQuery.php | 208 +++++++++++++++---------------------------- 3 files changed, 89 insertions(+), 160 deletions(-) diff --git a/.env.example b/.env.example index 41ac348..4f99eaf 100644 --- a/.env.example +++ b/.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 diff --git a/functions/Domain.php b/functions/Domain.php index d688142..fa1f23b 100644 --- a/functions/Domain.php +++ b/functions/Domain.php @@ -1,6 +1,8 @@ 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; + } } ?> diff --git a/models/icpQuery.php b/models/icpQuery.php index 9e5814c..60f2fcd 100644 --- a/models/icpQuery.php +++ b/models/icpQuery.php @@ -1,161 +1,56 @@ 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']); // 查询并输出域名备案信息 } - } }