214 lines
3.9 KiB
Go
214 lines
3.9 KiB
Go
|
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", NanoID())
|
||
|
|
||
|
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)
|
||
|
}
|
||
|
}
|