feat: geo ip.
This commit is contained in:
15
geoip/geoip.go
Normal file
15
geoip/geoip.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package geoip
|
||||
|
||||
// Result 归属地信息
|
||||
type Result struct {
|
||||
IP string `json:"ip"`
|
||||
Country string `json:"country"` // 国家
|
||||
Province string `json:"province"` // 省
|
||||
City string `json:"city"` // 城市
|
||||
ISP string `json:"isp"` // 服务提供商
|
||||
}
|
||||
|
||||
// GeoIP 客户端
|
||||
type GeoIP interface {
|
||||
Query(queryIp string) (res Result, err error)
|
||||
}
|
||||
1
geoip/geoip_test.go
Normal file
1
geoip/geoip_test.go
Normal file
@@ -0,0 +1 @@
|
||||
package geoip
|
||||
@@ -6,15 +6,11 @@ import (
|
||||
|
||||
"github.com/go-kratos/kratos/v2/log"
|
||||
"github.com/oschwald/geoip2-golang"
|
||||
|
||||
"github.com/tx7do/kratos-utils/geoip"
|
||||
"github.com/tx7do/kratos-utils/geoip/geolite/assets"
|
||||
)
|
||||
|
||||
type Result struct {
|
||||
Country string // 国家
|
||||
Province string // 省
|
||||
City string // 城市
|
||||
}
|
||||
|
||||
const defaultOutputLanguage = "zh-CN"
|
||||
|
||||
// Client 地理位置解析结构体
|
||||
@@ -56,7 +52,7 @@ func (g *Client) query(rawIP string) (city *geoip2.City, err error) {
|
||||
}
|
||||
|
||||
// Query 通过IP获取地区
|
||||
func (g *Client) Query(rawIP string) (ret Result, err error) {
|
||||
func (g *Client) Query(rawIP string) (ret geoip.Result, err error) {
|
||||
record, err := g.query(rawIP)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
||||
@@ -7,14 +7,3 @@ const (
|
||||
|
||||
redirectMode2 = 0x02 // RedirectMode2 国家的类型, 指向一个指向
|
||||
)
|
||||
|
||||
//var unCountry = []byte{"未知国家"}
|
||||
//var unArea = []byte{"未知地区"}
|
||||
|
||||
// Result 归属地信息
|
||||
type Result struct {
|
||||
IP string `json:"ip"`
|
||||
Country string `json:"country"`
|
||||
Area string `json:"area"`
|
||||
ISP string `json:"isp"`
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package qqwry
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"github.com/tx7do/kratos-utils/geoip"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -136,7 +137,10 @@ func (c *Client) readUInt24(offset int32) uint32 {
|
||||
return i
|
||||
}
|
||||
|
||||
func (c *Client) Query(queryIp string) (country, city, isp string, err error) {
|
||||
func (c *Client) Query(queryIp string) (res geoip.Result, err error) {
|
||||
res.IP = queryIp
|
||||
res.Country = "中国"
|
||||
|
||||
ip32, err := c.parseIp(queryIp)
|
||||
if err != nil {
|
||||
return
|
||||
@@ -152,7 +156,8 @@ func (c *Client) Query(queryIp string) (country, city, isp string, err error) {
|
||||
offset += 4
|
||||
mode := c.readMode(uint32(offset))
|
||||
|
||||
var _city []byte
|
||||
var _area []byte
|
||||
var area string
|
||||
|
||||
var ispPos uint32
|
||||
switch mode {
|
||||
@@ -164,25 +169,35 @@ func (c *Client) Query(queryIp string) (country, city, isp string, err error) {
|
||||
posCA = c.readUInt24(int32(posC) + 1)
|
||||
posC += 4
|
||||
}
|
||||
_city = c.readString(posCA)
|
||||
_area = c.readString(posCA)
|
||||
if mode != redirectMode2 {
|
||||
posC += uint32(len(city) + 1)
|
||||
posC += uint32(len(area) + 1)
|
||||
}
|
||||
ispPos = posC
|
||||
|
||||
case redirectMode2:
|
||||
posCA := c.readUInt24(offset + 1)
|
||||
_city = c.readString(posCA)
|
||||
_area = c.readString(posCA)
|
||||
ispPos = uint32(offset) + 4
|
||||
|
||||
default:
|
||||
posCA := offset + 0
|
||||
_city = c.readString(uint32(posCA))
|
||||
ispPos = uint32(offset) + uint32(len(city)) + 1
|
||||
_area = c.readString(uint32(posCA))
|
||||
ispPos = uint32(offset) + uint32(len(area)) + 1
|
||||
}
|
||||
|
||||
if len(_city) != 0 {
|
||||
city = strings.TrimSpace(gb18030Decode(_city))
|
||||
if len(_area) != 0 {
|
||||
area = strings.TrimSpace(gb18030Decode(_area))
|
||||
|
||||
areas := SpiltAddress(area)
|
||||
if len(areas) == 2 {
|
||||
res.Province = areas[0]
|
||||
res.City = areas[1]
|
||||
} else if len(areas) == 1 {
|
||||
res.City = areas[0]
|
||||
} else {
|
||||
res.City = area
|
||||
}
|
||||
}
|
||||
|
||||
ispMode := assets.QQWryDat[ispPos]
|
||||
@@ -192,10 +207,10 @@ func (c *Client) Query(queryIp string) (country, city, isp string, err error) {
|
||||
if ispPos > 0 {
|
||||
var _isp []byte
|
||||
_isp = c.readString(ispPos)
|
||||
isp = strings.TrimSpace(gb18030Decode(_isp))
|
||||
if isp != "" {
|
||||
if strings.Contains(isp, "CZ88.NET") {
|
||||
isp = ""
|
||||
res.ISP = strings.TrimSpace(gb18030Decode(_isp))
|
||||
if res.ISP != "" {
|
||||
if strings.Contains(res.ISP, "CZ88.NET") {
|
||||
res.ISP = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,20 @@ package qqwry
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestClient(t *testing.T) {
|
||||
g := NewClient()
|
||||
assert.NotNil(t, g)
|
||||
|
||||
country, city, isp, err := g.Query("47.108.149.89")
|
||||
res, err := g.Query("47.108.149.89")
|
||||
assert.Nil(t, err)
|
||||
fmt.Println("国家:", country, "城市:", city, "服务商:", isp)
|
||||
fmt.Println("国家:", res.Country, "省:", res.Province, "城市:", res.City, "服务商:", res.ISP)
|
||||
assert.Equal(t, res.Country, "中国")
|
||||
assert.Equal(t, res.Province, "四川省")
|
||||
assert.Equal(t, res.City, "成都市")
|
||||
assert.Equal(t, res.ISP, "阿里云")
|
||||
}
|
||||
|
||||
@@ -3,11 +3,14 @@ package qqwry
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"regexp"
|
||||
|
||||
"golang.org/x/text/encoding/simplifiedchinese"
|
||||
"golang.org/x/text/transform"
|
||||
)
|
||||
|
||||
var regSpiltAddress = regexp.MustCompile(`.+?(省|市|自治区|自治州|盟|县|区|管委会|街道|镇|乡)`)
|
||||
|
||||
func gb18030Decode(src []byte) string {
|
||||
in := bytes.NewReader(src)
|
||||
out := transform.NewReader(in, simplifiedchinese.GB18030.NewDecoder())
|
||||
@@ -26,3 +29,7 @@ func byte3ToUInt32(data []byte) uint32 {
|
||||
i |= (uint32(data[2]) << 16) & 0xff0000
|
||||
return i
|
||||
}
|
||||
|
||||
func SpiltAddress(addr string) []string {
|
||||
return regSpiltAddress.FindAllString(addr, -1)
|
||||
}
|
||||
|
||||
11
geoip/qqwry/utils_test.go
Normal file
11
geoip/qqwry/utils_test.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package qqwry
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSpiltAddress(t *testing.T) {
|
||||
names := SpiltAddress("浙江省杭州市西湖区")
|
||||
fmt.Println(names)
|
||||
}
|
||||
Reference in New Issue
Block a user