diff --git a/go.mod b/go.mod index 1de6fb8..30d9a4d 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( require ( github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/lionsoul2014/ip2region v2.2.0-release+incompatible // indirect github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/oschwald/maxminddb-golang v1.8.0 // indirect diff --git a/go.sum b/go.sum index 005483d..90096f9 100644 --- a/go.sum +++ b/go.sum @@ -244,6 +244,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lionsoul2014/ip2region v2.2.0-release+incompatible h1:1qp9iks+69h7IGLazAplzS9Ca14HAxuD5c0rbFdPGy4= +github.com/lionsoul2014/ip2region v2.2.0-release+incompatible/go.mod h1:+ZBN7PBoh5gG6/y0ZQ85vJDBe21WnfbRrQQwTfliJJI= github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= diff --git a/internal/db/db.go b/internal/db/db.go index 21504db..3962208 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -5,6 +5,8 @@ import ( "path/filepath" "strings" + "github.com/zu1k/nali/pkg/ip2region" + "github.com/zu1k/nali/internal/constant" "github.com/zu1k/nali/pkg/cdn" "github.com/zu1k/nali/pkg/dbif" @@ -19,6 +21,7 @@ var ( ZXIPv6WryPath = filepath.Join(constant.HomePath, "zxipv6wry.db") GeoLite2CityPath = filepath.Join(constant.HomePath, "GeoLite2-City.mmdb") IPIPFreePath = filepath.Join(constant.HomePath, "ipipfree.ipdb") + Ip2RegionPath = filepath.Join(constant.HomePath, "ip2region.db") CDNPath = filepath.Join(constant.HomePath, "cdn.json") Language = "zh-CN" @@ -80,6 +83,7 @@ func GetDB(typ dbif.QueryType) (db dbif.DB) { } func GetIPDBbyName(name string) (db dbif.DB) { + name = strings.ToLower(name) switch name { case "geo", "geoip", "geoip2": return geoip.NewGeoIP(GeoLite2CityPath) @@ -87,6 +91,8 @@ func GetIPDBbyName(name string) (db dbif.DB) { return qqwry.NewQQwry(QQWryPath) case "ipip", "ipipfree", "ipip.net": return ipip.NewIPIPFree(IPIPFreePath) + case "ip2region", "region", "i2r": + return ip2region.NewIp2Region(Ip2RegionPath) default: return qqwry.NewQQwry(QQWryPath) } diff --git a/pkg/dbif/db.go b/pkg/dbif/db.go index fb12850..c5fc4a6 100644 --- a/pkg/dbif/db.go +++ b/pkg/dbif/db.go @@ -5,6 +5,7 @@ import ( "github.com/zu1k/nali/pkg/cdn" "github.com/zu1k/nali/pkg/geoip" + "github.com/zu1k/nali/pkg/ip2region" "github.com/zu1k/nali/pkg/ipip" "github.com/zu1k/nali/pkg/qqwry" "github.com/zu1k/nali/pkg/zxipv6wry" @@ -27,5 +28,6 @@ var ( _ DB = zxipv6wry.ZXwry{} _ DB = ipip.IPIPFree{} _ DB = geoip.GeoIP{} + _ DB = ip2region.Ip2Region{} _ DB = cdn.CDN{} ) diff --git a/pkg/ip2region/ip2region.go b/pkg/ip2region/ip2region.go new file mode 100644 index 0000000..29e0b8e --- /dev/null +++ b/pkg/ip2region/ip2region.go @@ -0,0 +1,50 @@ +package ip2region + +import ( + "fmt" + "log" + "os" + + "github.com/lionsoul2014/ip2region/binding/golang/ip2region" + + "github.com/zu1k/nali/pkg/common" +) + +type Ip2Region struct { + db *ip2region.Ip2Region +} + +func NewIp2Region(filePath string) Ip2Region { + _, err := os.Stat(filePath) + if err != nil && os.IsNotExist(err) { + log.Println("文件不存在,尝试从网络获取最新 ip2region 库") + _, err = Download(filePath) + if err != nil { + os.Exit(1) + } + } + + region, err := ip2region.New(filePath) + if err != nil { + panic(err) + } + + return Ip2Region{ + db: region, + } +} + +func (db Ip2Region) Find(query string, params ...string) (result fmt.Stringer, err error) { + ip, err := db.db.MemorySearch(query) + if err != nil { + return nil, err + } + + fmt.Println(ip) + + result = common.Result{ + Country: ip.Country, + Area: ip.Province, + } + return result, nil +} diff --git a/pkg/ip2region/update.go b/pkg/ip2region/update.go new file mode 100644 index 0000000..1d13ec9 --- /dev/null +++ b/pkg/ip2region/update.go @@ -0,0 +1,49 @@ +package ip2region + +import ( + "io/ioutil" + "log" + "net/http" + + "github.com/zu1k/nali/pkg/common" +) + +func Download(filePath string) (data []byte, err error) { + data, err = getData() + if err != nil { + log.Printf("CDN数据库下载失败,请手动下载解压后保存到本地: %s \n", filePath) + log.Println("下载链接:", githubUrl) + return + } + + common.ExistThenRemove(filePath) + if err := ioutil.WriteFile(filePath, data, 0644); err == nil { + log.Printf("已将最新的 ip2region 保存到本地: %s \n", filePath) + } + return +} + +const ( + githubUrl = "https://raw.githubusercontent.com/lionsoul2014/ip2region/master/data/ip2region.db" + jsdelivrUrl = "https://cdn.jsdelivr.net/gh/lionsoul2014/ip2region/data/ip2region.db" +) + +func getData() (data []byte, err error) { + resp, err := http.Get(jsdelivrUrl) + if err != nil { + return nil, err + } + if resp.StatusCode != 200 { + resp, err = http.Get(githubUrl) + if err != nil { + return nil, err + } + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return body, nil +}