diff --git a/README.md b/README.md index 9b282f3d..28b0ca08 100644 --- a/README.md +++ b/README.md @@ -269,9 +269,13 @@ export NO_COLOR=1 nexttrace --data-provider ip-api.com ## Note There are frequency limits for free queries of the ipinfo and IPInsight APIs. You can purchase services from these providers to remove the limits ## If necessary, you can clone this project, add the token provided by ipinfo or IPInsight and compile it yourself +## Fill the token to: ipgeo/tokens.go + ## Note For the offline database IPInfoLocal, please download it manually and rename it to ipinfoLocal.mmdb. (You can download it from here: https://ipinfo.io/signup?ref=free-database-downloads) +## Current directory, nexttrace binary directory and FHS directories (Unix-like) will be searched. +## To customize it, please use environment variables, +export NEXTTRACE_IPINFOLOCALPATH=/xxx/yyy.mmdb ## For the offline database Ip2region, you can download it manually and rename it to ip2region.db, or let NextTrace download it automatically -## Fill the token to: ipgeo/tokens.go ## Please be aware: Due to the serious abuse of IP.SB, you will often be not able to query IP data from this source ## IP-API.com has a stricter restiction on API calls, if you can't query IP data from this source, please try again in a few minutes diff --git a/README_zh_CN.md b/README_zh_CN.md index 6b277693..e4f098e3 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -282,11 +282,15 @@ export NO_COLOR=1 nexttrace --data-provider ip-api.com ## 特别的: 其中 ipinfo 和 IPInsight API 对于免费版查询有频率限制,可从这些服务商自行购买服务以解除限制,如有需要可以 clone 本项目添加其提供的 token 自行编译 ## TOKEN填写路径:ipgeo/tokens.go -## 特别的: 对于离线库 IPInfoLocal,请自行下载并命名为 ipinfoLocal.mmdb (可以从这里下载:https://ipinfo.io/signup?ref=free-database-downloads) + +## 特别的: 对于离线库 IPInfoLocal,请自行下载并命名为 ipinfoLocal.mmdb +## (可以从这里下载:https://ipinfo.io/signup?ref=free-database-downloads), +## 默认搜索用户当前路径、程序所在路径、和 FHS 路径(Unix-like) +## 如果需要自定义路径,请设置环境变量 +export NEXTTRACE_IPINFOLOCALPATH=/xxx/yyy.mmdb ## 对于离线库 Ip2region 可NextTrace自动下载,也可自行下载并命名为 ip2region.db ## 另外:由于IP.SB被滥用比较严重,会经常出现无法查询的问题,请知悉。 ## IP-API.com限制调用较为严格,如有查询不到的情况,请几分钟后再试。 - # 纯真IP数据库默认使用 http://127.0.0.1:2060 作为查询接口,如需自定义请使用环境变量 export NEXTTRACE_CHUNZHENURL=http://127.0.0.1:2060 ## 可使用 https://github.com/freshcn/qqwry 自行搭建纯真IP数据库服务 diff --git a/ipgeo/ipinfoLocal.go b/ipgeo/ipinfoLocal.go index cb2ed1f3..65f415f9 100644 --- a/ipgeo/ipinfoLocal.go +++ b/ipgeo/ipinfoLocal.go @@ -2,24 +2,71 @@ package ipgeo import ( "errors" - "github.com/oschwald/maxminddb-golang" "net" "os" + "path/filepath" + "runtime" "strings" "time" + + "github.com/nxtrace/NTrace-core/util" + "github.com/oschwald/maxminddb-golang" ) const ( - ipinfoDataBasePath = "./ipinfoLocal.mmdb" + ipinfoDataBaseFilename = "ipinfoLocal.mmdb" ) +// Cache the path of the ipinfoLocal.mmdb file +var ipinfoDataBasePath = "" + +// We will try to get the path of the ipinfoLocal.mmdb file in the following order: +// 1. Use the value of the environment variable NEXTTRACE_IPINFOLOCALPATH +// 2. Search in the current folder and the executable folder +// 3. Search in /usr/local/share/nexttrace/ and /usr/share/nexttrace/ (for Unix/Linux) +// If the file is found, the path will be stored in the ipinfoDataBasePath variable +func getIPInfoLocalPath() (error) { + if ipinfoDataBasePath != "" { + return nil + } + // NEXTTRACE_IPINFOLOCALPATH + if util.EnvIPInfoLocalPath != "" { + if _, err := os.Stat(util.EnvIPInfoLocalPath); err == nil { + ipinfoDataBasePath = util.EnvIPInfoLocalPath + return nil + } else { + return errors.New("NEXTTRACE_IPINFOLOCALPATH is set but the file does not exist") + } + } + folders := []string{} + // current folder + if cur, err := os.Getwd(); err == nil { + folders = append(folders, cur + string(filepath.Separator)) + } + // exeutable folder + if exe, err := os.Executable(); err == nil { + folders = append(folders, filepath.Dir(exe) + string(filepath.Separator)) + } + if runtime.GOOS != "windows" { + folders = append(folders, "/usr/local/share/nexttrace/") + folders = append(folders, "/usr/share/nexttrace/") + } + for _, folder := range folders { + if _, err := os.Stat(folder + ipinfoDataBaseFilename); err == nil { + ipinfoDataBasePath = folder + ipinfoDataBaseFilename + return nil + } + } + return errors.New("no ipinfoLocal.mmdb found") +} + func IPInfoLocal(ip string, _ time.Duration, _ string, _ bool) (*IPGeoData, error) { - if _, err := os.Stat(ipinfoDataBasePath); os.IsNotExist(err) { + if err := getIPInfoLocalPath(); err != nil { panic("Cannot find ipinfoLocal.mmdb") } region, err := maxminddb.Open(ipinfoDataBasePath) if err != nil { - panic("Cannot find ipinfoLocal.mmdb") + panic("Cannot open ipinfoLocal.mmdb at " + ipinfoDataBasePath) } defer func(region *maxminddb.Reader) { err := region.Close() diff --git a/util/util.go b/util/util.go index 8a1623d2..476de684 100644 --- a/util/util.go +++ b/util/util.go @@ -18,6 +18,7 @@ import ( var Uninterrupted = GetenvDefault("NEXTTRACE_UNINTERRUPTED", "") var EnvToken = GetenvDefault("NEXTTRACE_TOKEN", "") +var EnvIPInfoLocalPath = GetenvDefault("NEXTTRACE_IPINFOLOCALPATH", "") var UserAgent = fmt.Sprintf("NextTrace %s/%s/%s", config.Version, runtime.GOOS, runtime.GOARCH) var RdnsCache sync.Map var PowProviderParam = ""