diff --git a/ipgeo/ipapicom.go b/ipgeo/ipapicom.go new file mode 100644 index 00000000..c4594a24 --- /dev/null +++ b/ipgeo/ipapicom.go @@ -0,0 +1,41 @@ +package ipgeo + +import ( + "io/ioutil" + "log" + "net/http" + "os" + "strings" + "time" + + "github.com/tidwall/gjson" +) + +func IPApiCom(ip string) (*IPGeoData, error) { + url := "http://ip-api.com/json/" + ip + "?fields=status,message,country,regionName,city,isp,as" + client := &http.Client{ + // 2 秒超时 + Timeout: 2 * time.Second, + } + req, _ := http.NewRequest("GET", url, nil) + req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0") + content, err := client.Do(req) + if err != nil { + log.Println("ip-api.com 请求超时(2s),请切换其他API使用") + return nil, err + } + body, _ := ioutil.ReadAll(content.Body) + res := gjson.ParseBytes(body) + + if res.Get("country").String() == "" { + os.Exit(1) + } + log.Println("ip-api.com 正在使用") + return &IPGeoData{ + Asnumber: strings.Split(res.Get("as").String(), " ")[0], + Country: res.Get("country").String(), + City: res.Get("city").String(), + Prov: res.Get("regionName").String(), + Isp: res.Get("isp").String(), + }, nil +} diff --git a/ipgeo/ipgeo.go b/ipgeo/ipgeo.go index be2ea19f..12c4ca2b 100644 --- a/ipgeo/ipgeo.go +++ b/ipgeo/ipgeo.go @@ -24,6 +24,8 @@ func GetSource(s string) Source { return IPSB case "IPINSIGHT": return IPInSight + case "ip-api.com": + return IPApiCom default: return nil } diff --git a/ipgeo/ipgeo_test.go b/ipgeo/ipgeo_test.go index 4f1c9829..c3904b64 100644 --- a/ipgeo/ipgeo_test.go +++ b/ipgeo/ipgeo_test.go @@ -41,3 +41,12 @@ func TestIPInSight(t *testing.T) { // 这个库有时候不提供城市信息,返回值为"" //assert.NotEmpty(t, res.City) } + +func TestIPApiCom(t *testing.T) { + res, err := IPApiCom("1.1.1.1") + assert.Nil(t, err) + assert.NotNil(t, res) + assert.NotEmpty(t, res.Country) + assert.NotEmpty(t, res.City) + assert.NotEmpty(t, res.Prov) +} diff --git a/main.go b/main.go index 53dfad9e..ee957281 100644 --- a/main.go +++ b/main.go @@ -30,7 +30,7 @@ var tablePrint = fSet.Bool("table", false, "Output trace results as table") var ver = fSet.Bool("V", false, "Check Version") func printArgHelp() { - fmt.Println("\nArgs Error\nUsage : 'nexttrace [option...] ' or 'nexttrace [option...]'\nOPTIONS: [-VTU] [-d DATAORIGIN.STR ] [ -m TTL ] [ -p PORT ] [ -q PROBES.COUNT ] [ -r PARALLELREQUESTS.COUNT ] [-rdns] [ -realtime | -table ] -report") + fmt.Println("\nArgs Error\nUsage : 'nexttrace [option...] HOSTNAME' or 'nexttrace HOSTNAME [option...]'\nOPTIONS: [-VTU] [-d DATAORIGIN.STR ] [ -m TTL ] [ -p PORT ] [ -q PROBES.COUNT ] [ -r PARALLELREQUESTS.COUNT ] [-rdns] [ -realtime | -table ] -report") fSet.PrintDefaults() os.Exit(2) }