103 lines
2.3 KiB
Go
103 lines
2.3 KiB
Go
/**
|
||
* package utils
|
||
* 作用:IP 归属地查询(基于本地 ip2region.xdb 离线库)
|
||
*/
|
||
package utils
|
||
|
||
import (
|
||
"log"
|
||
"strings"
|
||
"sync"
|
||
|
||
"github.com/lionsoul2014/ip2region/binding/golang/xdb"
|
||
)
|
||
|
||
var (
|
||
ipSearcher *xdb.Searcher
|
||
ipSearcherOnce sync.Once
|
||
ipSearcherErr error
|
||
ipCache sync.Map
|
||
)
|
||
|
||
/**
|
||
* InitIP2Region
|
||
* 功能:加载 ip2region.xdb,服务启动时调用一次
|
||
*/
|
||
func InitIP2Region(dbPath string) error {
|
||
ipSearcherOnce.Do(func() {
|
||
ipSearcher, ipSearcherErr = xdb.NewWithFileOnly(xdb.IPv4, dbPath)
|
||
if ipSearcherErr != nil {
|
||
log.Printf("❌ [IP2Region] 加载失败: %v", ipSearcherErr)
|
||
return
|
||
}
|
||
log.Printf("✅ [IP2Region] 已加载: %s", dbPath)
|
||
})
|
||
return ipSearcherErr
|
||
}
|
||
|
||
/**
|
||
* GetIPLocation
|
||
* 功能:查询 IP 归属地,内网/本地返回「本地」
|
||
*/
|
||
func GetIPLocation(ip string) string {
|
||
if isLocalIP(ip) {
|
||
return "本地"
|
||
}
|
||
if ip == "" {
|
||
return "未知"
|
||
}
|
||
|
||
if cached, ok := ipCache.Load(ip); ok {
|
||
return cached.(string)
|
||
}
|
||
|
||
if ipSearcher == nil {
|
||
return "未知"
|
||
}
|
||
|
||
region, err := ipSearcher.Search(ip)
|
||
if err != nil || region == "" {
|
||
return "未知"
|
||
}
|
||
|
||
// 格式: 国家|区域|省份|城市|ISP
|
||
parts := strings.Split(region, "|")
|
||
labels := []string{}
|
||
for _, p := range parts {
|
||
p = strings.TrimSpace(p)
|
||
if p != "" && p != "0" {
|
||
labels = append(labels, p)
|
||
}
|
||
}
|
||
result := "未知"
|
||
if len(labels) > 0 {
|
||
result = strings.Join(labels, " ")
|
||
}
|
||
ipCache.Store(ip, result)
|
||
return result
|
||
}
|
||
|
||
/**
|
||
* isLocalIP
|
||
* 功能:判断是否为本地/内网 IP
|
||
*/
|
||
func isLocalIP(ip string) bool {
|
||
if ip == "127.0.0.1" || ip == "localhost" || ip == "::1" {
|
||
return true
|
||
}
|
||
if strings.HasPrefix(ip, "192.168.") || strings.HasPrefix(ip, "10.") {
|
||
return true
|
||
}
|
||
if strings.HasPrefix(ip, "172.16.") || strings.HasPrefix(ip, "172.17.") ||
|
||
strings.HasPrefix(ip, "172.18.") || strings.HasPrefix(ip, "172.19.") ||
|
||
strings.HasPrefix(ip, "172.20.") || strings.HasPrefix(ip, "172.21.") ||
|
||
strings.HasPrefix(ip, "172.22.") || strings.HasPrefix(ip, "172.23.") ||
|
||
strings.HasPrefix(ip, "172.24.") || strings.HasPrefix(ip, "172.25.") ||
|
||
strings.HasPrefix(ip, "172.26.") || strings.HasPrefix(ip, "172.27.") ||
|
||
strings.HasPrefix(ip, "172.28.") || strings.HasPrefix(ip, "172.29.") ||
|
||
strings.HasPrefix(ip, "172.30.") || strings.HasPrefix(ip, "172.31.") {
|
||
return true
|
||
}
|
||
return false
|
||
}
|