package task import ( //"crypto/tls" //"fmt" "io" "log" "net" "net/http" "strings" "sync" "time" ) var ( Httping bool HttpingStatusCode int HttpingCFColo string HttpingCFColomap *sync.Map ) // pingReceived pingTotalTime func (p *Ping) httping(ip *net.IPAddr) (int, time.Duration) { hc := http.Client{ Timeout: time.Second * 2, Transport: &http.Transport{ DialContext: getDialContext(ip), //TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // 跳过证书验证 }, CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse // 阻止重定向 }, } // 先访问一次获得 HTTP 状态码 及 Cloudflare Colo { requ, err := http.NewRequest(http.MethodHead, URL, nil) if err != nil { return 0, 0 } requ.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36") resp, err := hc.Do(requ) if err != nil { return 0, 0 } defer resp.Body.Close() //fmt.Println("IP:", ip, "StatusCode:", resp.StatusCode, resp.Request.URL) if HttpingStatusCode == 0 || HttpingStatusCode < 100 && HttpingStatusCode > 599 { if resp.StatusCode != 200 && resp.StatusCode != 301 && resp.StatusCode != 302 { return 0, 0 } } else { if resp.StatusCode != HttpingStatusCode { return 0, 0 } } io.Copy(io.Discard, resp.Body) if HttpingCFColo != "" { cfRay := resp.Header.Get("CF-RAY") colo := p.getColo(cfRay) if colo == "" { return 0, 0 } } } // 循环测速计算延迟 success := 0 var delay time.Duration for i := 0; i < PingTimes; i++ { requ, err := http.NewRequest(http.MethodHead, URL, nil) if err != nil { log.Fatal("意外的错误,情报告:", err) return 0, 0 } requ.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36") if i == PingTimes-1 { requ.Header.Set("Connection", "close") } startTime := time.Now() resp, err := hc.Do(requ) if err != nil { continue } success++ io.Copy(io.Discard, resp.Body) _ = resp.Body.Close() duration := time.Since(startTime) delay += duration } return success, delay } func MapColoMap() *sync.Map { if HttpingCFColo == "" { return nil } colos := strings.Split(HttpingCFColo, ",") colomap := &sync.Map{} for _, colo := range colos { colomap.Store(colo, colo) } return colomap } func (p *Ping) getColo(b string) string { if b == "" { return "" } idColo := strings.Split(b, "-") out := idColo[1] if HttpingCFColomap == nil { return out } _, ok := HttpingCFColomap.Load(out) if ok { return out } return "" }