github.com/nxtrace/NTrace-core@v1.3.1-0.20240513132635-39169291e8c9/ipgeo/ipapicom.go (about)

     1  package ipgeo
     2  
     3  import (
     4  	"errors"
     5  	"github.com/nxtrace/NTrace-core/util"
     6  	"io"
     7  	"log"
     8  	"net/http"
     9  	"regexp"
    10  	"strconv"
    11  	"time"
    12  
    13  	"github.com/tidwall/gjson"
    14  )
    15  
    16  func IPApiCom(ip string, timeout time.Duration, _ string, _ bool) (*IPGeoData, error) {
    17  	url := "http://ip-api.com/json/" + ip + "?fields=status,message,country,regionName,city,isp,district,as,lat,lon"
    18  	client := &http.Client{
    19  		// 2 秒超时
    20  		Timeout: timeout,
    21  	}
    22  	req, _ := http.NewRequest("GET", url, nil)
    23  	req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0")
    24  	content, err := client.Do(req)
    25  	if err != nil {
    26  		log.Println("ip-api.com 请求超时(2s),请切换其他API使用")
    27  		return nil, err
    28  	}
    29  	body, _ := io.ReadAll(content.Body)
    30  	res := gjson.ParseBytes(body)
    31  
    32  	if res.Get("status").String() != "success" {
    33  		return &IPGeoData{}, errors.New("超过API阈值")
    34  	}
    35  
    36  	re := regexp.MustCompile("[0-9]+")
    37  	var country = res.Get("country").String()
    38  	var prov = res.Get("region").String()
    39  	var city = res.Get("city").String()
    40  	var district = res.Get("district").String()
    41  	if util.StringInSlice(country, []string{"Hong Kong", "Taiwan", "Macao"}) {
    42  		district = prov + " " + city + " " + district
    43  		city = country
    44  		prov = ""
    45  		country = "China"
    46  	}
    47  	lat, _ := strconv.ParseFloat(res.Get("lat").String(), 32)
    48  	lng, _ := strconv.ParseFloat(res.Get("lon").String(), 32)
    49  
    50  	return &IPGeoData{
    51  		Asnumber: re.FindString(res.Get("as").String()),
    52  		Country:  country,
    53  		City:     city,
    54  		Prov:     prov,
    55  		District: district,
    56  		Owner:    res.Get("isp").String(),
    57  		Lat:      lat,
    58  		Lng:      lng,
    59  	}, nil
    60  }