From afad52b41f9fe2c5a3281c085bb88d25089ba4a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=85=89=E6=98=A5?= Date: Tue, 5 Sep 2023 10:52:28 +0800 Subject: [PATCH] - update goip --- .gitignore | 9 +++- utils/goip/client.go | 82 ++++++++++++++++++++++++++++--- utils/goip/geoip/client.go | 45 +++++++++++++++-- utils/goip/geoip/query.go | 15 ++++++ utils/goip/ip2region/client.go | 22 +++++++-- utils/goip/ip2region/qqery.go | 10 ++++ utils/goip/ip2region_v2/client.go | 26 ++++++++-- utils/goip/ip2region_v2/query.go | 11 +++++ utils/goip/ipv6wry/client.go | 30 +++++++++-- utils/goip/ipv6wry/query.go | 14 +++++- utils/goip/qqwry/client.go | 30 +++++++++-- utils/goip/qqwry/query.go | 10 ++++ utils/goip/query.go | 5 +- 13 files changed, 278 insertions(+), 31 deletions(-) diff --git a/.gitignore b/.gitignore index 2fbbb56c..4427045a 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,11 @@ *_test.go /service/*_test.go /utils/*_test.go -*.text \ No newline at end of file +*.text +/utils/goip/geoip/GeoLite2-ASN.mmdb +/utils/goip/geoip/GeoLite2-City.mmdb +/utils/goip/geoip/GeoLite2-Country.mmdb +/utils/goip/ip2region/ip2region.db +/utils/goip/ip2region_v2/ip2region.xdb +/utils/goip/ipv6wry/ipv6wry.db +/utils/goip/qqwry/qqwry.dat \ No newline at end of file diff --git a/utils/goip/client.go b/utils/goip/client.go index feb8ab72..265d2094 100644 --- a/utils/goip/client.go +++ b/utils/goip/client.go @@ -8,6 +8,23 @@ import ( "github.com/dtapps/go-library/utils/goip/qqwry" ) +type ClientConfig struct { + Ip2regionPath string + Ip2regionByte []byte + Ip2regionV2Path string + Ip2regionV2Byte []byte + QqwryPath string + QqwryByte []byte + Ipv6wryPath string + Ipv6wryByte []byte + GeoipAsnPath string + GeoipAsnByte []byte + GeoipCityPath string + GeoipCityByte []byte + GeoipCountryPath string + GeoipCountryByte []byte +} + type Client struct { ip2regionV2Client *ip2region_v2.Client ip2regionClient *ip2region.Client @@ -17,21 +34,72 @@ type Client struct { } // NewIp 实例化 -func NewIp() *Client { +func NewIp(config ClientConfig) (*Client, error) { + var err error c := &Client{} - c.ip2regionV2Client, _ = ip2region_v2.New() + if config.Ip2regionV2Path == "" { + c.ip2regionV2Client, err = ip2region_v2.NewBuff(config.Ip2regionV2Byte) + if err != nil { + return nil, err + } + } else { + c.ip2regionV2Client, err = ip2region_v2.New(config.Ip2regionV2Path) + if err != nil { + return nil, err + } + } - c.ip2regionClient = ip2region.New() + if config.Ip2regionPath == "" { + c.ip2regionClient, err = ip2region.NewBuff(config.Ip2regionByte) + if err != nil { + return nil, err + } + } else { + c.ip2regionClient, err = ip2region.New(config.Ip2regionPath) + if err != nil { + return nil, err + } + } - c.qqwryClient = qqwry.New() + if config.QqwryPath == "" { + c.qqwryClient, err = qqwry.NewBuff(config.QqwryByte) + if err != nil { + return nil, err + } + } else { + c.qqwryClient, err = qqwry.New(config.QqwryPath) + if err != nil { + return nil, err + } + } - c.geoIpClient, _ = geoip.New() + if config.GeoipAsnPath == "" || config.GeoipCityPath == "" || config.GeoipCountryPath == "" { + c.geoIpClient, err = geoip.NewBuff(config.GeoipAsnByte, config.GeoipCityByte, config.GeoipCountryByte) + if err != nil { + return nil, err + } + } else { + c.geoIpClient, err = geoip.New(config.GeoipAsnPath, config.GeoipCityPath, config.GeoipCountryPath) + if err != nil { + return nil, err + } + } - c.ipv6wryClient = ipv6wry.New() + if config.Ipv6wryPath == "" { + c.ipv6wryClient, err = ipv6wry.NewBuff(config.Ipv6wryByte) + if err != nil { + return nil, err + } + } else { + c.ipv6wryClient, err = ipv6wry.New(config.Ipv6wryPath) + if err != nil { + return nil, err + } + } - return c + return c, nil } func (c *Client) Close() { diff --git a/utils/goip/geoip/client.go b/utils/goip/geoip/client.go index 3bb9d012..97da10a1 100644 --- a/utils/goip/geoip/client.go +++ b/utils/goip/geoip/client.go @@ -1,17 +1,14 @@ package geoip import ( - _ "embed" "github.com/oschwald/geoip2-golang" + "os" ) -//go:embed GeoLite2-ASN.mmdb var asnBuff []byte -//go:embed GeoLite2-City.mmdb var cityBuff []byte -//go:embed GeoLite2-Country.mmdb var countryBuff []byte type Client struct { @@ -20,21 +17,33 @@ type Client struct { countryDb *geoip2.Reader } -func New() (*Client, error) { +func New(asnFilepath string, cityFilepath string, countryFilepath string) (*Client, error) { var err error c := &Client{} + asnBuff, err = os.ReadFile(asnFilepath) + if err != nil { + return nil, err + } c.asnDb, err = geoip2.FromBytes(asnBuff) if err != nil { return nil, err } + cityBuff, err = os.ReadFile(cityFilepath) + if err != nil { + return nil, err + } c.cityDb, err = geoip2.FromBytes(cityBuff) if err != nil { return nil, err } + countryBuff, err = os.ReadFile(countryFilepath) + if err != nil { + return nil, err + } c.countryDb, err = geoip2.FromBytes(countryBuff) if err != nil { return nil, err @@ -43,6 +52,32 @@ func New() (*Client, error) { return c, err } +func NewBuff(asnFile []byte, cityFile []byte, countryFile []byte) (*Client, error) { + + var err error + c := &Client{} + + asnBuff = asnFile + c.asnDb, err = geoip2.FromBytes(asnFile) + if err != nil { + return nil, err + } + + cityBuff = cityFile + c.cityDb, err = geoip2.FromBytes(cityFile) + if err != nil { + return nil, err + } + + countryBuff = countryFile + c.countryDb, err = geoip2.FromBytes(countryFile) + if err != nil { + return nil, err + } + + return c, err +} + func (c *Client) Close() { c.asnDb.Close() diff --git a/utils/goip/geoip/query.go b/utils/goip/geoip/query.go index e9b34a83..90edb3f5 100644 --- a/utils/goip/geoip/query.go +++ b/utils/goip/geoip/query.go @@ -2,7 +2,9 @@ package geoip import ( _ "embed" + "errors" "net" + "strings" ) // QueryCityResult 返回 @@ -64,3 +66,16 @@ func (c *Client) QueryCity(ipAddress net.IP) (result QueryCityResult, err error) return result, err } + +// QueryCityIP ip地址查询对应归属地信息 +func (c *Client) QueryCityIP(ipAddressStr string) (result QueryCityResult, err error) { + arrIpv4 := strings.Split(ipAddressStr, ".") + if len(arrIpv4) == 4 { + return c.QueryCity(net.ParseIP(ipAddressStr)) + } + arrIpv6 := strings.Split(ipAddressStr, ":") + if len(arrIpv6) == 8 { + return c.QueryCity(net.ParseIP(ipAddressStr)) + } + return QueryCityResult{}, errors.New("不是IP") +} diff --git a/utils/goip/ip2region/client.go b/utils/goip/ip2region/client.go index 72eb2cb9..41a0be83 100644 --- a/utils/goip/ip2region/client.go +++ b/utils/goip/ip2region/client.go @@ -1,7 +1,6 @@ package ip2region import ( - _ "embed" "errors" "github.com/dtapps/go-library/utils/gostring" "os" @@ -13,7 +12,6 @@ const ( IndexBlockLength = 12 ) -//go:embed ip2region.db var dbBuff []byte type Client struct { @@ -37,11 +35,27 @@ type Client struct { dbFile string } -func New() *Client { +func New(filepath string) (*Client, error) { + var err error c := &Client{} - return c + dbBuff, err = os.ReadFile(filepath) + if err != nil { + return nil, err + } + + return c, nil +} + +func NewBuff(file []byte) (*Client, error) { + + var _ error + c := &Client{} + + dbBuff = file + + return c, nil } // 获取Ip信息 diff --git a/utils/goip/ip2region/qqery.go b/utils/goip/ip2region/qqery.go index 330dedcf..4c81ba4f 100644 --- a/utils/goip/ip2region/qqery.go +++ b/utils/goip/ip2region/qqery.go @@ -4,6 +4,7 @@ import ( "errors" "net" "strconv" + "strings" ) type QueryResult struct { @@ -71,3 +72,12 @@ func (c *Client) Query(ipAddress net.IP) (result QueryResult, err error) { return result, nil } + +// QueryIP ip地址查询对应归属地信息 +func (c *Client) QueryIP(ipAddressStr string) (result QueryResult, err error) { + arrIpv4 := strings.Split(ipAddressStr, ".") + if len(arrIpv4) == 4 { + return c.Query(net.ParseIP(ipAddressStr)) + } + return QueryResult{}, errors.New("不是IPV4") +} diff --git a/utils/goip/ip2region_v2/client.go b/utils/goip/ip2region_v2/client.go index 92136438..ee5a74d8 100644 --- a/utils/goip/ip2region_v2/client.go +++ b/utils/goip/ip2region_v2/client.go @@ -1,20 +1,40 @@ package ip2region_v2 -import _ "embed" +import "os" -//go:embed ip2region.xdb var cBuff []byte type Client struct { db *Searcher } -func New() (*Client, error) { +func New(filepath string) (*Client, error) { var err error c := &Client{} // 1、从 dbPath 加载整个 xdb 到内存 + cBuff, err = os.ReadFile(filepath) + if err != nil { + return nil, err + } + + // 2、用全局的 cBuff 创建完全基于内存的查询对象。 + c.db, err = NewWithBuffer(cBuff) + if err != nil { + return nil, err + } + + return c, err +} + +func NewBuff(file []byte) (*Client, error) { + + var err error + c := &Client{} + + // 1、从 dbPath 加载整个 xdb 到内存 + cBuff = file // 2、用全局的 cBuff 创建完全基于内存的查询对象。 c.db, err = NewWithBuffer(cBuff) diff --git a/utils/goip/ip2region_v2/query.go b/utils/goip/ip2region_v2/query.go index 760edac9..e087cd68 100644 --- a/utils/goip/ip2region_v2/query.go +++ b/utils/goip/ip2region_v2/query.go @@ -2,8 +2,10 @@ package ip2region_v2 import ( _ "embed" + "errors" "github.com/dtapps/go-library/utils/gostring" "net" + "strings" ) // QueryResult 返回 @@ -50,3 +52,12 @@ func (c *Client) Query(ipAddress net.IP) (result QueryResult, err error) { return result, err } + +// QueryIP ip地址查询对应归属地信息 +func (c *Client) QueryIP(ipAddressStr string) (result QueryResult, err error) { + arrIpv4 := strings.Split(ipAddressStr, ".") + if len(arrIpv4) == 4 { + return c.Query(net.ParseIP(ipAddressStr)) + } + return QueryResult{}, errors.New("不是IPV4") +} diff --git a/utils/goip/ipv6wry/client.go b/utils/goip/ipv6wry/client.go index f07ca913..39361eff 100644 --- a/utils/goip/ipv6wry/client.go +++ b/utils/goip/ipv6wry/client.go @@ -1,9 +1,9 @@ package ipv6wry import ( - _ "embed" "encoding/binary" "log" + "os" ) var ( @@ -16,7 +16,6 @@ var ( end uint32 ) -//go:embed ipv6wry.db var datBuff []byte type Client struct { @@ -25,10 +24,33 @@ type Client struct { IndexLen uint32 } -func New() *Client { +func New(filepath string) (*Client, error) { + var err error c := &Client{} + datBuff, err = os.ReadFile(filepath) + if err != nil { + return nil, err + } + + buf := datBuff[0:8] + start := binary.LittleEndian.Uint32(buf[:4]) + end := binary.LittleEndian.Uint32(buf[4:]) + + num := int64((end-start)/7 + 1) + log.Printf("ipv6wry.db 共加载:%d 条ip记录\n", num) + + return c, nil +} + +func NewBuff(file []byte) (*Client, error) { + + var _ error + c := &Client{} + + datBuff = file + buf := datBuff[0:8] start := binary.LittleEndian.Uint32(buf[:4]) end := binary.LittleEndian.Uint32(buf[4:]) @@ -36,7 +58,7 @@ func New() *Client { num := int64((end-start)/7 + 1) log.Printf("ipv6wry.db 共加载:%d 条ip记录\n", num) - return c + return c, nil } // ReadData 从文件中读取数据 diff --git a/utils/goip/ipv6wry/query.go b/utils/goip/ipv6wry/query.go index 8d000c95..fb054179 100644 --- a/utils/goip/ipv6wry/query.go +++ b/utils/goip/ipv6wry/query.go @@ -1,6 +1,7 @@ package ipv6wry import ( + "errors" "github.com/dtapps/go-library/utils/gostring" "math/big" "net" @@ -18,7 +19,7 @@ type QueryResult struct { } // Query ip地址查询对应归属地信息 -func (c *Client) Query(ipAddress net.IP) (result QueryResult) { +func (c *Client) Query(ipAddress net.IP) (result QueryResult, err error) { result.Ip = ipAddress.String() @@ -78,5 +79,14 @@ func (c *Client) Query(ipAddress net.IP) (result QueryResult) { result.Isp = gostring.SpaceAndLineBreak(result.Isp) - return result + return result, nil +} + +// QueryIP ip地址查询对应归属地信息 +func (c *Client) QueryIP(ipAddressStr string) (result QueryResult, err error) { + arrIpv6 := strings.Split(ipAddressStr, ":") + if len(arrIpv6) == 8 { + return c.Query(net.ParseIP(ipAddressStr)) + } + return QueryResult{}, errors.New("不是IPV6") } diff --git a/utils/goip/qqwry/client.go b/utils/goip/qqwry/client.go index 3b514454..a9a17b35 100644 --- a/utils/goip/qqwry/client.go +++ b/utils/goip/qqwry/client.go @@ -1,9 +1,9 @@ package qqwry import ( - _ "embed" "encoding/binary" "log" + "os" ) var ( @@ -15,7 +15,6 @@ var ( end uint32 ) -//go:embed qqwry.dat var datBuff []byte type Client struct { @@ -24,10 +23,33 @@ type Client struct { IndexLen uint32 } -func New() *Client { +func New(filepath string) (*Client, error) { + var err error c := &Client{} + datBuff, err = os.ReadFile(filepath) + if err != nil { + return nil, err + } + + buf := datBuff[0:8] + start := binary.LittleEndian.Uint32(buf[:4]) + end := binary.LittleEndian.Uint32(buf[4:]) + + num := int64((end-start)/7 + 1) + log.Printf("qqwry.dat 共加载:%d 条ip记录\n", num) + + return c, nil +} + +func NewBuff(file []byte) (*Client, error) { + + var _ error + c := &Client{} + + datBuff = file + buf := datBuff[0:8] start := binary.LittleEndian.Uint32(buf[:4]) end := binary.LittleEndian.Uint32(buf[4:]) @@ -35,7 +57,7 @@ func New() *Client { num := int64((end-start)/7 + 1) log.Printf("qqwry.dat 共加载:%d 条ip记录\n", num) - return c + return c, nil } // ReadData 从文件中读取数据 diff --git a/utils/goip/qqwry/query.go b/utils/goip/qqwry/query.go index 12457e2b..cade48f6 100644 --- a/utils/goip/qqwry/query.go +++ b/utils/goip/qqwry/query.go @@ -6,6 +6,7 @@ import ( "github.com/dtapps/go-library/utils/gostring" "golang.org/x/text/encoding/simplifiedchinese" "net" + "strings" ) // QueryResult 返回 @@ -51,3 +52,12 @@ func (c *Client) Query(ipAddress net.IP) (result QueryResult, err error) { return result, nil } + +// QueryIP ip地址查询对应归属地信息 +func (c *Client) QueryIP(ipAddressStr string) (result QueryResult, err error) { + arrIpv4 := strings.Split(ipAddressStr, ".") + if len(arrIpv4) == 4 { + return c.Query(net.ParseIP(ipAddressStr)) + } + return QueryResult{}, errors.New("不是IPV4") +} diff --git a/utils/goip/query.go b/utils/goip/query.go index b250f1dd..8204243d 100644 --- a/utils/goip/query.go +++ b/utils/goip/query.go @@ -81,7 +81,10 @@ func (c *Client) QueryIpv6wry(ipAddress net.IP) (result ipv6wry.QueryResult, err return result, QueryIncorrect } - query := c.ipv6wryClient.Query(ipAddress) + query, err := c.ipv6wryClient.Query(ipAddress) + if err != nil { + return ipv6wry.QueryResult{}, err + } return query, nil }