package utils import ( "bytes" "errors" "fmt" "io" "net" "net/http" "os" "strconv" "strings" ) 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() (localIp string) { localIp = "127.0.0.1" // Get all network interfaces interfaces, err := net.Interfaces() if err != nil { return } for _, iface := range interfaces { // Skip the loopback interface if iface.Flags&net.FlagLoopback != 0 { continue } // Get addresses associated with the interface addrs, err := iface.Addrs() if err != nil { continue } for _, addr := range addrs { // Check if the address is an IPNet ipnet, ok := addr.(*net.IPNet) if !ok || ipnet.IP.IsLoopback() { continue } // Get the IP address ip := ipnet.IP.To4() if ip == nil { continue } // Skip IP addresses in the 169.254.x.x range if strings.HasPrefix(ip.String(), "169.254") { continue } // Skip IP addresses in the 169.254.x.x range if strings.HasPrefix(ip.String(), "26.26") { continue } // Return the first valid IP address found return ip.String() } } return } 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) } }