package utils import ( "bytes" "errors" "fmt" "io" "net" "net/http" "os" "strconv" ) func IsPublicIP(ipString string) bool { ip := net.ParseIP(ipString) if ip.IsLoopback() || ip.IsLinkLocalMulticast() || ip.IsLinkLocalUnicast() { return false } if ip4 := ip.To4(); ip4 != nil { switch true { case ip4[0] == 10: return false case ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31: return false case ip4[0] == 192 && ip4[1] == 168: return false default: return true } } return false } // Get Location IP . func GetLocationIP() string { addrs, err := net.InterfaceAddrs() if err != nil { return "" } ip := "" for _, a := range addrs { if ipnet, ok := a.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { if ipnet.IP.To4() != nil { ip = ipnet.IP.String() break } } } if ip == "" { return "" } return ip } func LocalIPv4s() ([]string, error) { var ips []string addrs, _ := net.InterfaceAddrs() for _, addr := range addrs { if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { if ipnet.IP.To4() != nil { locIP := ipnet.IP.To4().String() if locIP[0:7] != "169.254" { ips = append(ips, locIP) } } } } return ips, nil } func GetOutBoundIP() (ip string, err error) { body, err := HttpGet("http://ip.dhcp.cn/?ip") // 获取外网 IP return string(body), err } func HttpGet(url string) ([]byte, error) { resp, err := http.Get(url) if err != nil { // handle error return nil, err } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) return body, err } func HttpPost(url string, header map[string]string, data []byte) ([]byte, error) { var err error reader := bytes.NewBuffer(data) request, err := http.NewRequest("POST", url, reader) if err != nil { return nil, err } request.Header.Set("Content-Type", "application/json;charset=UTF-8") request.Header.Set("Request-Id", ULID()) for key, val := range header { request.Header.Set(key, val) } client := http.Client{} resp, err := client.Do(request) if err != nil { return nil, err } defer resp.Body.Close() respBytes, err := io.ReadAll(resp.Body) if err != nil { return nil, err } if resp.StatusCode != 200 { return nil, errors.New(string(respBytes)) } return respBytes, nil } func HttpRequest(r *http.Request) ([]byte, error) { var err error client := http.Client{} resp, err := client.Do(r) if err != nil { return nil, err } defer resp.Body.Close() respBytes, err := io.ReadAll(resp.Body) if err != nil { return nil, err } return respBytes, nil } func DownloadFile(url, saveTo string, fb func(length, downLen int64)) { var ( fsize int64 buf = make([]byte, 32*1024) written int64 ) //创建一个http client client := new(http.Client) //get方法获取资源 resp, err := client.Get(url) if err != nil { fmt.Printf("download %s error:%s\n", url, err) os.Exit(0) } //读取服务器返回的文件大小 fsize, err = strconv.ParseInt(resp.Header.Get("Content-Length"), 10, 32) if err != nil { fmt.Println(err) } //创建文件 file, err := os.Create(saveTo) file.Chmod(0777) if err != nil { fmt.Printf("Create %s error:%s\n", saveTo, err) os.Exit(0) } defer file.Close() if resp.Body == nil { fmt.Printf("resp %s error:%s\n", url, err) os.Exit(0) } defer resp.Body.Close() //下面是 io.copyBuffer() 的简化版本 for { //读取bytes nr, er := resp.Body.Read(buf) if nr > 0 { //写入bytes nw, ew := file.Write(buf[0:nr]) //数据长度大于0 if nw > 0 { written += int64(nw) } //写入出错 if ew != nil { err = ew break } //读取是数据长度不等于写入的数据长度 if nr != nw { err = io.ErrShortWrite break } } if er != nil { if er != io.EOF { err = er } break } //没有错误了快使用 callback fb(fsize, written) } if err != nil { fmt.Printf("callback error:%s\n", err) os.Exit(0) } }