💩 优化获取 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 ( import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"math/rand"
"net/http" "net/http"
"strings" "strings"
"time" "time"
@ -19,11 +20,11 @@ type geoIP struct {
var ( var (
geoIPApiList = []string{ geoIPApiList = []string{
"https://api.ip.sb/geoip", "https://api.ip.sb/geoip",
"https://ip.seeip.org/geoip",
"https://ipapi.co/json", "https://ipapi.co/json",
"https://freegeoip.app/json/", "https://freegeoip.app/json/",
"http://ip-api.com/json/", "http://ip-api.com/json/",
"https://extreme-ip-lookup.com/json/", "https://extreme-ip-lookup.com/json/",
// "https://ip.seeip.org/geoip",
} }
cachedIP, cachedCountry string cachedIP, cachedCountry string
httpClientV4 = utils.NewSingleStackHTTPClient(time.Second*20, time.Second*5, time.Second*10, false) 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 ip geoIP
var resp *http.Response var resp *http.Response
var err error var err error
for i := 0; i < len(servers); i++ { if isV6 {
if isV6 { resp, err = httpGetWithUA(httpClientV6, servers[rand.Intn(len(servers))])
resp, err = httpClientV6.Get(servers[i]) } else {
} else { resp, err = httpGetWithUA(httpClientV4, servers[rand.Intn(len(servers))])
resp, err = httpClientV4.Get(servers[i]) }
} if err != nil {
if err == nil { return ip
body, err := ioutil.ReadAll(resp.Body) }
if err != nil { body, err := ioutil.ReadAll(resp.Body)
continue if err != nil {
} return ip
resp.Body.Close() }
err = utils.Json.Unmarshal(body, &ip) resp.Body.Close()
if err != nil { err = utils.Json.Unmarshal(body, &ip)
continue if err != nil {
} return ip
if ip.IP == "" && ip.Query != "" { }
ip.IP = ip.Query if ip.IP == "" && ip.Query != "" {
} ip.IP = ip.Query
// 没取到 v6 IP }
if isV6 && !strings.Contains(ip.IP, ":") { // 没取到 v6 IP
continue if isV6 && !strings.Contains(ip.IP, ":") {
} return ip
// 没取到 v4 IP }
if !isV6 && !strings.Contains(ip.IP, ".") { // 没取到 v4 IP
continue if !isV6 && !strings.Contains(ip.IP, ".") {
} return ip
return 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)
}