diff --git a/backend/getInfo.php b/backend/getInfo.php new file mode 100644 index 0000000..f2c269a --- /dev/null +++ b/backend/getInfo.php @@ -0,0 +1,173 @@ +getDistrict($ip); // 获取IPIP.net数据 + $data = IPinfo::getInfo($ip); // 获取ipinfo.io数据 + $country = getCountry($data['country']); // 解析国家2位编码 + $qqwry = new QQWry('qqwry.dat'); + $detail = $qqwry->getDetail($ip); // 获取纯真IP数据 + $info['ip'] = $data['ip']; + $info['as'] = $data['as']; + $info['city'] = $data['city']; + $info['region'] = $data['region']; + if (isset($data['country'])) { + $info['country'] = $data['country']; + if (isset($country['en'])) { + $info['country'] .= ' - ' . $country['en']; + $info['country'] .= "(" . $country['cn'] . ")"; + } + } + $info['timezone'] = $data['timezone']; + $info['loc'] = $data['loc']; + $info['isp'] = $data['isp']; + if ($detail['country'] == '中国') { + $info['country'] = 'CN - China(中国)'; + $info['timezone'] = 'Asia/Shanghai'; + if ($detail['region'] == '台湾') { // 修正台湾数据带 "市" 或 "县" 的情况 + if (mb_substr($detail['city'], -1) == '市' || mb_substr($detail['city'], -1) == '县') { + $detail['city'] = mb_substr($detail['city'], 0, mb_strlen($detail['city']) - 1); + } + } + if ($detail['region'] == '' && $detail['city'] == '') { // 纯真库解析不出数据 + if ($addr[1] != '' || $addr[2] != '') { // IPIP数据不同时为空 + $detail['region'] = $addr[1]; + $detail['city'] = $addr[2]; + } + } else if ($detail['region'] == '' || $detail['city'] == '') { // 纯真库存在空数据 + if ($addr[1] != '' && $addr[2] != '') { // IPIP数据完整 + $detail['region'] = $addr[1]; // 修正纯真数据 + $detail['city'] = $addr[2]; + } + } + if ($detail['region'] != '' || $detail['city'] != '') { // 修正后数据不同时为空 + $cityLoc = getLoc($detail['region'], $detail['city']); // 获取城市经纬度 + if ($cityLoc['region'] != '香港' && $cityLoc['region'] != '澳门' && $cityLoc['region'] != '台湾') { // 跳过港澳台数据 + $info['region'] = $cityLoc['region']; + $info['city'] = $cityLoc['city']; + $info['loc'] = $cityLoc['lat'] . ',' . $cityLoc['lon']; + } + } + if ($detail['isp'] == '教育网') { // 载入纯真库分析出的ISP数据 + $info['isp'] = 'China Education and Research Network'; + } else if ($detail['isp'] == '电信') { + $info['isp'] = 'China Telecom'; + } else if ($detail['isp'] == '联通') { + $info['isp'] = 'China Unicom Limited'; + } else if ($detail['isp'] == '移动') { + $info['isp'] = 'China Mobile Communications Corporation'; + } else if ($detail['isp'] == '铁通') { + $info['isp'] = 'China Tietong Telecom'; + } else if ($detail['isp'] == '广电网') { + $info['isp'] = 'Shaanxi Broadcast & TV Network Intermediary'; + } else if ($detail['isp'] == '鹏博士') { + $info['isp'] = 'Chengdu Dr.Peng Technology'; + } else if ($detail['isp'] == '长城') { + $info['isp'] = 'Great Wall Broadband Network Service'; + } else if ($detail['isp'] == '中华电信') { + $info['isp'] = 'ChungHwa Telecom'; + } else if ($detail['isp'] == '亚太电信') { + $info['isp'] = 'Asia Pacific Telecom'; + } else if ($detail['isp'] == '远传电信') { + $info['isp'] = 'Far EasTone Telecommunications'; + } + } + if (filter_var($ip, \FILTER_VALIDATE_IP,\FILTER_FLAG_IPV4)) { // 录入纯真库数据 + $info['scope'] = tryCIDR($detail['beginIP'], $detail['endIP']); + $info['detail'] = $detail['dataA'] . $detail['dataB']; + } else { + $info['scope'] = $info['ip']; + $info['detail'] = $info['as'] . ' ' . $info['isp']; + } + } + + if ($_GET['cli'] == "true") { // 使用命令行模式 + $cli = "IP: ".$info['ip'] . PHP_EOL; + $cli .= "AS: ".$info['as'] . PHP_EOL; + $cli .= "City: ".$info['city'] . PHP_EOL; + $cli .= "Region: ".$info['region'] . PHP_EOL; + $cli .= "Country: ".$info['country'] . PHP_EOL; + $cli .= "Timezone: ".$info['timezone'] . PHP_EOL; + $cli .= "Location: ".$info['loc'] . PHP_EOL; + $cli .= "ISP: ".$info['isp'] . PHP_EOL; + $cli .= "Scope: ".$info['scope'] . PHP_EOL; + $cli .= "Detail: ".$info['detail'] . PHP_EOL; + return $cli; + } + + $info['status'] = 'T'; + header('Content-Type: application/json; charset=utf-8'); // 以JSON格式发送 + return json_encode($info); +} + +function checkSpecial($ip) { // 检查特殊IP地址并返回说明 + if ('::1' === $ip) { + $info['en'] = 'localhost IPv6 access'; + $info['cn'] = '本地IPv6地址'; + } + if (stripos($ip, 'fe80:') === 0) { + $info['en'] = 'link-local IPv6 access'; + $info['cn'] = '链路本地IPv6地址'; + } + if (strpos($ip, '127.') === 0) { + $info['en'] = 'localhost IPv4 access'; + $info['cn'] = '本地IPv4地址'; + } + if (strpos($ip, '10.') === 0) { + $info['en'] = 'private IPv4 access'; + $info['cn'] = '私有IPv4地址'; + } + if (preg_match('/^172\.(1[6-9]|2\d|3[01])\./', $ip) === 1) { + $info['en'] = 'private IPv4 access'; + $info['cn'] = '私有IPv4地址'; + } + if (strpos($ip, '192.168.') === 0) { + $info['en'] = 'private IPv4 access'; + $info['cn'] = '私有IPv4地址'; + } + if (strpos($ip, '169.254.') === 0) { + $info['en'] = 'link-local IPv4 access'; + $info['cn'] = '链路本地IPv4地址'; + } + return isset($info) ? $info : null; +} + +function tryCIDR($beginIP, $endIP) { // 给定IP范围,尝试计算CIDR + $tmp = ip2long($endIP) - ip2long($beginIP) + 1; + if (pow(2, intval(log($tmp, 2))) == $tmp) { // 判断是否为2的整数次方 + return $beginIP . '/' . (32 - log($tmp, 2)); + } else { + return $beginIP . ' - ' . $endIP; + } +} + +function getVersion() { // 获取自身及数据库版本号 + global $myVersion; + $version['echoip'] = $myVersion; + $qqwry = new QQWry('qqwry.dat'); + $IPIP = new IPDB('ipipfree.ipdb'); + $version['qqwry'] = $qqwry->getVersion(); + $version['ipip'] = $IPIP->getVersion(); + return $version; +} + +?> \ No newline at end of file diff --git a/backend/queryInfo.php b/backend/queryInfo.php index 757e550..6a6a624 100644 --- a/backend/queryInfo.php +++ b/backend/queryInfo.php @@ -1,177 +1,48 @@ getDistrict($ip); // 获取IPIP.net数据 - $data = IPinfo::getInfo($ip); // 获取ipinfo.io数据 - $country = getCountry($data['country']); // 解析国家2位编码 - $qqwry = new QQWry('qqwry.dat'); - $detail = $qqwry->getDetail($ip); // 获取纯真IP数据 - $info['ip'] = $data['ip']; - $info['as'] = $data['as']; - $info['city'] = $data['city']; - $info['region'] = $data['region']; - if (isset($data['country'])) { - $info['country'] = $data['country']; - if (isset($country['en'])) { - $info['country'] .= ' - ' . $country['en']; - $info['country'] .= "(" . $country['cn'] . ")"; - } - } - $info['timezone'] = $data['timezone']; - $info['loc'] = $data['loc']; - $info['isp'] = $data['isp']; - if ($detail['country'] == '中国') { - $info['country'] = 'CN - China(中国)'; - $info['timezone'] = 'Asia/Shanghai'; - if ($detail['region'] == '台湾') { // 修正台湾数据带 "市" 或 "县" 的情况 - if (mb_substr($detail['city'], -1) == '市' || mb_substr($detail['city'], -1) == '县') { - $detail['city'] = mb_substr($detail['city'], 0, mb_strlen($detail['city']) - 1); - } - } - if ($detail['region'] == '' && $detail['city'] == '') { // 纯真库解析不出数据 - if ($addr[1] != '' || $addr[2] != '') { // IPIP数据不同时为空 - $detail['region'] = $addr[1]; - $detail['city'] = $addr[2]; - } - } else if ($detail['region'] == '' || $detail['city'] == '') { // 纯真库存在空数据 - if ($addr[1] != '' && $addr[2] != '') { // IPIP数据完整 - $detail['region'] = $addr[1]; // 修正纯真数据 - $detail['city'] = $addr[2]; - } - } - if ($detail['region'] != '' || $detail['city'] != '') { // 修正后数据不同时为空 - $cityLoc = getLoc($detail['region'], $detail['city']); // 获取城市经纬度 - if ($cityLoc['region'] != '香港' && $cityLoc['region'] != '澳门' && $cityLoc['region'] != '台湾') { // 跳过港澳台数据 - $info['region'] = $cityLoc['region']; - $info['city'] = $cityLoc['city']; - $info['loc'] = $cityLoc['lat'] . ',' . $cityLoc['lon']; - } - } - if ($detail['isp'] == '教育网') { // 载入纯真库分析出的ISP数据 - $info['isp'] = 'China Education and Research Network'; - } else if ($detail['isp'] == '电信') { - $info['isp'] = 'China Telecom'; - } else if ($detail['isp'] == '联通') { - $info['isp'] = 'China Unicom Limited'; - } else if ($detail['isp'] == '移动') { - $info['isp'] = 'China Mobile Communications Corporation'; - } else if ($detail['isp'] == '铁通') { - $info['isp'] = 'China Tietong Telecom'; - } else if ($detail['isp'] == '广电网') { - $info['isp'] = 'Shaanxi Broadcast & TV Network Intermediary'; - } else if ($detail['isp'] == '鹏博士') { - $info['isp'] = 'Chengdu Dr.Peng Technology'; - } else if ($detail['isp'] == '长城') { - $info['isp'] = 'Great Wall Broadband Network Service'; - } else if ($detail['isp'] == '中华电信') { - $info['isp'] = 'ChungHwa Telecom'; - } else if ($detail['isp'] == '亚太电信') { - $info['isp'] = 'Asia Pacific Telecom'; - } else if ($detail['isp'] == '远传电信') { - $info['isp'] = 'Far EasTone Telecommunications'; - } - } - if (filter_var($ip, \FILTER_VALIDATE_IP,\FILTER_FLAG_IPV4)) { // 录入纯真库数据 - $info['scope'] = tryCIDR($detail['beginIP'], $detail['endIP']); - $info['detail'] = $detail['dataA'] . $detail['dataB']; - } else { - $info['scope'] = $info['ip']; - $info['detail'] = $info['as'] . ' ' . $info['isp']; - } - } +function getClientIP() { // 获取客户端IP + return isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']; +} - if ($_GET['cli'] == "true") { // 使用命令行模式 - $cli = "IP: ".$info['ip'] . PHP_EOL; - $cli .= "AS: ".$info['as'] . PHP_EOL; - $cli .= "City: ".$info['city'] . PHP_EOL; - $cli .= "Region: ".$info['region'] . PHP_EOL; - $cli .= "Country: ".$info['country'] . PHP_EOL; - $cli .= "Timezone: ".$info['timezone'] . PHP_EOL; - $cli .= "Location: ".$info['loc'] . PHP_EOL; - $cli .= "ISP: ".$info['isp'] . PHP_EOL; - $cli .= "Scope: ".$info['scope'] . PHP_EOL; - $cli .= "Detail: ".$info['detail'] . PHP_EOL; - return $cli; - } - - $info['status'] = 'T'; - header('Content-Type: application/json; charset=utf-8'); // 以JSON格式发送 - return json_encode($info); +function formatDate($str) { // 将YYYYMMDD处理为YYYY-MM-DD + return substr($str, 0, 4) . '-' . substr($str, 4, 2) . '-' . substr($str, 6, 2); } -function checkSpecial($ip) { // 检查特殊IP地址并返回说明 - if ('::1' === $ip) { - $info['en'] = 'localhost IPv6 access'; - $info['cn'] = '本地IPv6地址'; - } - if (stripos($ip, 'fe80:') === 0) { - $info['en'] = 'link-local IPv6 access'; - $info['cn'] = '链路本地IPv6地址'; - } - if (strpos($ip, '127.') === 0) { - $info['en'] = 'localhost IPv4 access'; - $info['cn'] = '本地IPv4地址'; - } - if (strpos($ip, '10.') === 0) { - $info['en'] = 'private IPv4 access'; - $info['cn'] = '私有IPv4地址'; +function preRount() { // 解析请求路径 + global $request; + $requestUri = $_SERVER['DOCUMENT_URI']; + if ($_GET['cli'] == 'true') { + $request['cli'] = true; } - if (preg_match('/^172\.(1[6-9]|2\d|3[01])\./', $ip) === 1) { - $info['en'] = 'private IPv4 access'; - $info['cn'] = '私有IPv4地址'; + if ($requestUri == '/' || $requestUri == '/ip') { // URI -> / or /ip + $request['justip'] = true; + return; + } else if ($requestUri == '/version') { // URI -> /version + $request['version'] = true; + return; + } else if ($requestUri == '/info') { // URI -> /info + $request['ip'] = getClientIP(); + return; + } else if ($requestUri == '/query') { // URI -> /query?xxx=xxx + if ($_GET['error'] == 'true') { $request['error'] = true; } + if ($_GET['version'] == 'true') { $request['version'] = true; } + if ($_GET['justip'] == 'true') { $request['justip'] = true; } + if (isset($_GET['ip'])) { $request['ip'] = $_GET['ip']; } + return; } - if (strpos($ip, '192.168.') === 0) { - $info['en'] = 'private IPv4 access'; - $info['cn'] = '私有IPv4地址'; + preg_match('#^/([^/]+?)$#', $requestUri, $match); // URI -> /{ip} + if (count($match) > 0) { + $request['ip'] = $match[1]; + return; } - if (strpos($ip, '169.254.') === 0) { - $info['en'] = 'link-local IPv4 access'; - $info['cn'] = '链路本地IPv4地址'; + preg_match('#^/info/([^/]+?)$#', $requestUri, $match); // URI -> /info/{ip} + if (count($match) > 0) { + $request['ip'] = $match[1]; + return; } - return isset($info) ? $info : null; -} - -function tryCIDR($beginIP, $endIP) { // 给定IP范围,尝试计算CIDR - $tmp = ip2long($endIP) - ip2long($beginIP) + 1; - if (pow(2, intval(log($tmp, 2))) == $tmp) { // 判断是否为2的整数次方 - return $beginIP . '/' . (32 - log($tmp, 2)); - } else { - return $beginIP . ' - ' . $endIP; - } -} - -function getVersion() { // 获取自身及数据库版本号 - global $myVersion; - $version['echoip'] = $myVersion; - $qqwry = new QQWry('qqwry.dat'); - $IPIP = new IPDB('ipipfree.ipdb'); - $version['qqwry'] = $qqwry->getVersion(); - $version['ipip'] = $IPIP->getVersion(); - return $version; -} - -function formatDate($str) { // 将YYYYMMDD处理为YYYY-MM-DD - return substr($str, 0, 4) . '-' . substr($str, 4, 2) . '-' . substr($str, 6, 2); + $request['error'] = true; } function routeParam() { @@ -181,19 +52,20 @@ function routeParam() { // justip -> 仅查询IP地址 // ip -> 请求指定IP的数据 - if ($_GET['error'] == "true") { // 请求出错 - if ($_GET['cli'] == "true") { // 命令行模式 + global $request; + if ($request['error']) { // 请求出错 + if ($request['cli']) { // 命令行模式 echo 'Illegal Request' . PHP_EOL; } else { header('HTTP/1.1 302 Moved Temporarily'); header('Location: /error'); } - exit; // 退出程序 + exit; // 退出 } - if ($_GET['version'] == "true") { // 请求版本信息 + if ($request['version']) { // 请求版本信息 $version = getVersion(); - if ($_GET['cli'] == "true") { // 命令行模式 + if ($request['cli']) { // 命令行模式 echo "echoip -> " . $version['echoip'] . PHP_EOL; echo "qqwry.dat -> " . formatDate($version['qqwry']) . PHP_EOL; echo "ipip.net -> " . formatDate($version['ipip']) . PHP_EOL; @@ -201,23 +73,22 @@ function routeParam() { header('Content-Type: application/json; charset=utf-8'); echo json_encode($version); // 返回JSON数据 } - exit; // 退出程序 + exit; // 退出 } - $ip = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']; // 获取客户端IP - if ($_GET['justip'] == "true") { // 仅查询IP地址 - if ($_GET['cli'] == "true") { // 命令行模式 - echo $ip . PHP_EOL; + if ($request['justip']) { // 仅查询IP地址 + if ($request['cli']) { // 命令行模式 + echo getClientIP() . PHP_EOL; } else { header('Content-Type: application/json; charset=utf-8'); - echo '{"ip":"' . $ip . '"}'; // 返回JSON数据 + echo '{"ip":"' . getClientIP() . '"}'; // 返回JSON数据 } exit; } - $ip = isset($_GET['ip']) ? $_GET['ip'] : $ip; // 若存在请求信息则查询该IP + $ip = isset($request['ip']) ? $request['ip'] : getClientIP(); // 若存在请求信息则查询该IP if (!filter_var($ip, \FILTER_VALIDATE_IP)) { // 输入IP不合法 - if ($_GET['cli'] == "true") { // 命令行模式 + if ($request['cli']) { // 命令行模式 echo "Illegal Request" . PHP_EOL; } else { $reply = array(); @@ -228,12 +99,22 @@ function routeParam() { } exit; } - echo getIPInfo($ip); + echo getIPInfo($ip); // 查询目标IP } function main() { - routeParam(); // 处理传入参数 + preRount(); // 解析请求路径 + routeParam(); // 处理请求参数 } $myVersion = 'v1.2'; +$request = array( + 'error' => false, + 'version' => false, + 'cli' => false, + 'justip' => false, +); + main(); + +?> \ No newline at end of file