aipdw/aipdw.go

86 lines
1.9 KiB
Go
Raw Normal View History

package aipdw
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net"
"net/http"
"sync"
"time"
)
var (
client = &http.Client{Timeout: 5 * time.Second}
ipCache = &sync.Map{}
)
type Body struct {
Status string `json:"status"` // 返回结果状态值值为0或1,0表示失败1表示成功
Info string `json:"info"` // status为0时info返回错误原因否则返回“OK”
Infocode string `json:"infocode"` // 返回状态说明,10000代表正确,详情参阅info状态表
Result
}
type Result struct {
Country string `json:"country"` // 国家
Province string `json:"province"` // 省份
City string `json:"city"` // 城市
District string `json:"district"` // 区县
Isp string `json:"isp"` // 运营商
Location string `json:"location"` // 经纬度
IP string `json:"ip"` // IP地址
}
// QueryIP 使用高德位置服务查询IP
func QueryIP(sk string, key string, ip string) (result Result, err error) {
v, ok := ipCache.Load(ip)
if ok {
result = v.(Result)
return
}
pip := net.ParseIP(ip)
if pip == nil {
err = errors.New("ip is not ipv4 or ipv6")
return
}
ipt := "6"
if pip.To4() != nil {
ipt = "4"
}
arg := &reqLBS{
SK: sk,
Args: map[string]string{
"ip": ip,
"key": key,
"type": ipt,
},
}
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s?%s", "https://restapi.amap.com/v5/ip", arg.Encode()), nil)
if err != nil {
return
}
resp, err := client.Do(req)
if err != nil {
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return
}
var bodyUnmarshal Body
err = json.Unmarshal(body, &bodyUnmarshal)
if err != nil {
return
}
if bodyUnmarshal.Infocode != "10000" {
err = fmt.Errorf("resp code is %s, body is %s", bodyUnmarshal.Infocode, body)
return
}
result = bodyUnmarshal.Result
ipCache.Store(ip, bodyUnmarshal.Result)
return
}