💩 优化获取 GeoIP

This commit is contained in:
naiba 2022-03-31 22:45:26 +08:00
parent 5c127bc03f
commit 1f051459bb
2 changed files with 68 additions and 30 deletions

View File

@ -3,6 +3,7 @@ package monitor
import (
"fmt"
"io/ioutil"
"math/rand"
"net/http"
"strings"
"time"
@ -19,11 +20,11 @@ type geoIP struct {
var (
geoIPApiList = []string{
"https://api.ip.sb/geoip",
"https://ip.seeip.org/geoip",
"https://ipapi.co/json",
"https://freegeoip.app/json/",
"http://ip-api.com/json/",
"https://extreme-ip-lookup.com/json/",
// "https://ip.seeip.org/geoip",
}
cachedIP, cachedCountry string
httpClientV4 = utils.NewSingleStackHTTPClient(time.Second*20, time.Second*5, time.Second*10, false)
@ -56,35 +57,42 @@ func fetchGeoIP(servers []string, isV6 bool) geoIP {
var ip geoIP
var resp *http.Response
var err error
for i := 0; i < len(servers); i++ {
if isV6 {
resp, err = httpClientV6.Get(servers[i])
} else {
resp, err = httpClientV4.Get(servers[i])
}
if err == nil {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
continue
}
resp.Body.Close()
err = utils.Json.Unmarshal(body, &ip)
if err != nil {
continue
}
if ip.IP == "" && ip.Query != "" {
ip.IP = ip.Query
}
// 没取到 v6 IP
if isV6 && !strings.Contains(ip.IP, ":") {
continue
}
// 没取到 v4 IP
if !isV6 && !strings.Contains(ip.IP, ".") {
continue
}
return ip
}
if isV6 {
resp, err = httpGetWithUA(httpClientV6, servers[rand.Intn(len(servers))])
} else {
resp, err = httpGetWithUA(httpClientV4, servers[rand.Intn(len(servers))])
}
if err != nil {
return ip
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return ip
}
resp.Body.Close()
err = utils.Json.Unmarshal(body, &ip)
if err != nil {
return ip
}
if ip.IP == "" && ip.Query != "" {
ip.IP = ip.Query
}
// 没取到 v6 IP
if isV6 && !strings.Contains(ip.IP, ":") {
return ip
}
// 没取到 v4 IP
if !isV6 && !strings.Contains(ip.IP, ".") {
return ip
}
return ip
}
func httpGetWithUA(client *http.Client, url string) (*http.Response, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
req.Header.Add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Safari/537.36")
return client.Do(req)
}

View File

@ -0,0 +1,30 @@
package monitor
import (
"io/ioutil"
"testing"
"github.com/stretchr/testify/assert"
"github.com/naiba/nezha/pkg/utils"
)
func TestGeoIPApi(t *testing.T) {
for i := 0; i < len(geoIPApiList); i++ {
resp, err := httpGetWithUA(httpClientV4, geoIPApiList[i])
assert.Nil(t, err)
body, err := ioutil.ReadAll(resp.Body)
assert.Nil(t, err)
resp.Body.Close()
var ip geoIP
err = utils.Json.Unmarshal(body, &ip)
assert.Nil(t, err)
t.Logf("%s %s %s %s", geoIPApiList[i], ip.CountryCode, utils.IPDesensitize(ip.IP), utils.IPDesensitize(ip.Query))
assert.True(t, ip.IP != "" || ip.Query != "")
}
}
func TestFetchGeoIP(t *testing.T) {
ip := fetchGeoIP(geoIPApiList, false)
assert.NotEmpty(t, ip.IP)
}