diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..77c6356 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea/ +.vscode/ +.devcontainer/ diff --git a/README.md b/README.md index 6c9c5e8..986b879 100644 --- a/README.md +++ b/README.md @@ -1 +1,2 @@ -# tipdw \ No newline at end of file +# tipdw +Golang 腾讯IP定位库 \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..bc6affa --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/xiaoqidun/tipdw + +go 1.17 diff --git a/tipdw.go b/tipdw.go new file mode 100644 index 0000000..3c2b53a --- /dev/null +++ b/tipdw.go @@ -0,0 +1,72 @@ +package tipdw + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "time" +) + +var client = &http.Client{Timeout: 5 * time.Second} + +type Body struct { + Status int `json:"status"` + Message string `json:"message"` + Result Result `json:"result"` +} + +type Result struct { + IP string `json:"ip"` + AdInfo AdInfo `json:"ad_info"` + Location Location `json:"location"` +} + +type AdInfo struct { + Nation string `json:"nation"` + Province string `json:"province"` + City string `json:"city"` + District string `json:"district"` + Adcode int `json:"adcode"` +} + +type Location struct { + Lat float64 `json:"lat"` + Lng float64 `json:"lng"` +} + +// QueryIP 使用腾讯位置服务查询IP +func QueryIP(sk string, key string, ip string) (result Result, err error) { + arg := &reqLBS{ + SK: sk, + Path: "/ws/location/v1/ip", + Args: map[string]string{ + "ip": ip, + "key": key, + }, + } + req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s?%s", "https://apis.map.qq.com/ws/location/v1/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.Status != 0 { + err = fmt.Errorf("resp code is %d, body is %s", bodyUnmarshal.Status, body) + return + } + result = bodyUnmarshal.Result + return +} diff --git a/tipdw_util.go b/tipdw_util.go new file mode 100644 index 0000000..934d4de --- /dev/null +++ b/tipdw_util.go @@ -0,0 +1,43 @@ +package tipdw + +import ( + "crypto/md5" + "encoding/hex" + "fmt" + "net/url" + "sort" + "strings" +) + +type reqLBS struct { + SK string + Path string + Args map[string]string +} + +func (r *reqLBS) Encode() string { + r.Signature() + req := url.Values{} + for k, v := range r.Args { + req.Set(k, v) + } + return req.Encode() +} + +func (r *reqLBS) Signature() { + if r.Args == nil { + r.Args = make(map[string]string) + } + var keys []string + for k := range r.Args { + keys = append(keys, k) + } + sort.Strings(keys) + var keyValue []string + for i := 0; i < len(keys); i++ { + keyValue = append(keyValue, fmt.Sprintf("%s=%s", keys[i], r.Args[keys[i]])) + } + signStr := r.Path + "?" + strings.Join(keyValue, "&") + r.SK + signMd5 := md5.Sum([]byte(signStr)) + r.Args["sig"] = hex.EncodeToString(signMd5[:]) +}