package lib import ( "bytes" "crypto/md5" "encoding/binary" "encoding/hex" "fmt" "io/ioutil" "math/rand" "net" "net/http" "net/url" "os" "regexp" "strings" "time" ) var TimeLocation *time.Location var TimeFormat = "2006-01-02 15:04:05" var DateFormat = "2006-01-02" var LocalIP = net.ParseIP("127.0.0.1") func HttpGET( urlString string, urlParams url.Values, msTimeout int, header http.Header) (*http.Response, []byte, error) { client := http.Client{ Timeout: time.Duration(msTimeout) * time.Millisecond, } urlString = AddGetDataToUrl(urlString, urlParams) req, err := http.NewRequest("GET", urlString, nil) if err != nil { return nil, nil, err } if len(header) > 0 { req.Header = header } resp, err := client.Do(req) if err != nil { return nil, nil, err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, nil, err } return resp, body, nil } func HttpPOST(urlString string, urlParams url.Values, msTimeout int, header http.Header, contextType string) (*http.Response, []byte, error) { client := http.Client{ Timeout: time.Duration(msTimeout) * time.Millisecond, } if contextType == "" { contextType = "application/x-www-form-urlencoded" } urlParamEncode := urlParams.Encode() req, err := http.NewRequest("POST", urlString, strings.NewReader(urlParamEncode)) if len(header) > 0 { req.Header = header } req.Header.Set("Content-Type", contextType) resp, err := client.Do(req) if err != nil { return nil, nil, err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, nil, err } return resp, body, nil } func HttpJSON(urlString string, jsonContent string, msTimeout int, header http.Header) (*http.Response, []byte, error) { client := http.Client{ Timeout: time.Duration(msTimeout) * time.Millisecond, } req, err := http.NewRequest("POST", urlString, strings.NewReader(jsonContent)) if len(header) > 0 { req.Header = header } req.Header.Set("Content-Type", "application/json") resp, err := client.Do(req) if err != nil { return nil, nil, err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, nil, err } return resp, body, nil } func AddGetDataToUrl(urlString string, data url.Values) string { if strings.Contains(urlString, "?") { urlString = urlString + "&" } else { urlString = urlString + "?" } return fmt.Sprintf("%s%s", urlString, data.Encode()) } func addTrace2Header(request *http.Request, trace *TraceContext) *http.Request { traceId := trace.TraceId cSpanId := NewSpanId() if traceId != "" { request.Header.Set("didi-header-rid", traceId) } if cSpanId != "" { request.Header.Set("didi-header-spanid", cSpanId) } trace.CSpanId = cSpanId return request } func GetMd5Hash(text string) string { hasher := md5.New() hasher.Write([]byte(text)) return hex.EncodeToString(hasher.Sum(nil)) } func Encode(data string) (string, error) { h := md5.New() _, err := h.Write([]byte(data)) if err != nil { return "", err } return hex.EncodeToString(h.Sum(nil)), nil } func ParseServerAddr(serverAddr string) (host, port string) { serverInfo := strings.Split(serverAddr, ":") if len(serverInfo) == 2 { host = serverInfo[0] port = serverInfo[1] } else { host = serverAddr port = "" } return host, port } func NewTrace() *TraceContext { trace := &TraceContext{} trace.TraceId = GetTraceId() trace.SpanId = NewSpanId() return trace } func NewSpanId() string { timestamp := uint32(time.Now().Unix()) ipToLong := binary.BigEndian.Uint32(LocalIP.To4()) b := bytes.Buffer{} b.WriteString(fmt.Sprintf("%08x", ipToLong^timestamp)) b.WriteString(fmt.Sprintf("%08x", rand.Int31())) return b.String() } func GetTraceId() (traceId string) { return calcTraceId(LocalIP.String()) } func calcTraceId(ip string) (traceId string) { now := time.Now() timestamp := uint32(now.Unix()) timeNano := now.UnixNano() pid := os.Getpid() b := bytes.Buffer{} netIP := net.ParseIP(ip) if netIP == nil { b.WriteString("00000000") } else { b.WriteString(hex.EncodeToString(netIP.To4())) } b.WriteString(fmt.Sprintf("%08x", timestamp&0xffffffff)) b.WriteString(fmt.Sprintf("%04x", timeNano&0xffff)) b.WriteString(fmt.Sprintf("%04x", pid&0xffff)) b.WriteString(fmt.Sprintf("%06x", rand.Int31n(1<<24))) b.WriteString("b0") // 末两位标记来源,b0为go return b.String() } func GetLocalIPs() (ips []net.IP) { interfaceAddr, err := net.InterfaceAddrs() if err != nil { return nil } for _, address := range interfaceAddr { ipNet, isValidIpNet := address.(*net.IPNet) if isValidIpNet && !ipNet.IP.IsLoopback() { if ipNet.IP.To4() != nil { ips = append(ips, ipNet.IP) } } } return ips } func InArrayString(s string, arr []string) bool { for _, i := range arr { if i == s { return true } } return false } //Substr 字符串的截取 func Substr(str string, start int64, end int64) string { length := int64(len(str)) if start < 0 || start > length { return "" } if end < 0 { return "" } if end > length { end = length } return string(str[start:end]) } //利用正则表达式压缩字符串,去除空格或制表符 func CompressStr(str string) string { if str == "" { return "" } //匹配一个或多个空白符的正则表达式 reg := regexp.MustCompile("\\s+") return reg.ReplaceAllString(str, "") } func ClientIP(r *http.Request) string { xForwardedFor := r.Header.Get("X-Forwarded-For") ip := strings.TrimSpace(strings.Split(xForwardedFor, ",")[0]) if ip != "" { return ip } ip = strings.TrimSpace(r.Header.Get("X-Real-Ip")) if ip != "" { return ip } if ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr)); err == nil { return ip } return "" }