mirror of
https://github.com/xiaoqidun/qqwry.git
synced 2026-01-10 07:30:22 +08:00
76 lines
1.8 KiB
Go
76 lines
1.8 KiB
Go
package qqwry
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
|
|
"github.com/ipipdotnet/ipdb-go"
|
|
)
|
|
|
|
const (
|
|
dataTypeDat = 0
|
|
dataTypeIpdb = 1
|
|
)
|
|
|
|
// Client IP查询客户端
|
|
// 字段: data DAT数据库, dataLen DAT数据库长度, ipdbCity IPDB数据库, dataType 数据类型, cache 结果缓存
|
|
type Client struct {
|
|
data []byte
|
|
dataLen uint32
|
|
ipdbCity *ipdb.City
|
|
dataType int
|
|
cache *Cache
|
|
}
|
|
|
|
// NewClient 创建新的IP查询客户端
|
|
// 入参: filePath 文件路径
|
|
// 返回: c 客户端实例, err 错误信息
|
|
func NewClient(filePath string) (c *Client, err error) {
|
|
body, err := os.ReadFile(filePath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return NewClientFromData(body)
|
|
}
|
|
|
|
// NewClientFromData 从数据创建新的IP查询客户端
|
|
// 入参: body DAT数据库或IPDB数据库
|
|
// 返回: c 客户端实例, err 错误信息
|
|
func NewClientFromData(body []byte) (c *Client, err error) {
|
|
c = &Client{}
|
|
c.cache = NewCache(10000)
|
|
if len(body) > 11 && string(body[6:11]) == "build" {
|
|
c.dataType = dataTypeIpdb
|
|
c.ipdbCity, err = ipdb.NewCityFromBytes(body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
} else {
|
|
c.dataType = dataTypeDat
|
|
c.data = body
|
|
c.dataLen = uint32(len(c.data))
|
|
}
|
|
return c, nil
|
|
}
|
|
|
|
// QueryIP 查询IP
|
|
// 入参: ip IP地址
|
|
// 返回: location 位置信息, err 错误信息
|
|
func (c *Client) QueryIP(ip string) (location *Location, err error) {
|
|
if v, ok := c.cache.Get(ip); ok {
|
|
return v.Clone(), nil
|
|
}
|
|
switch c.dataType {
|
|
case dataTypeDat:
|
|
location, err = c.queryIPDat(ip)
|
|
case dataTypeIpdb:
|
|
location, err = c.queryIPIpdb(ip)
|
|
default:
|
|
return nil, errors.New("data type not support")
|
|
}
|
|
if err == nil && location != nil {
|
|
c.cache.Add(ip, location)
|
|
}
|
|
return location, err
|
|
}
|