package main import ( "encoding/json" "fmt" "io/ioutil" "net/http" "sync" ) type ProxiesResponse struct { Proxies map[string]interface{} `json:"proxies"` } func check(url string, wg *sync.WaitGroup) { defer wg.Done() for retry := 0; retry < 3; retry++ { resp, err := http.Get(url) if err != nil { fmt.Printf("Error: %s - %s\n", url, err) continue } defer resp.Body.Close() if resp.StatusCode == http.StatusOK { fmt.Printf("Success: %s\n", url) return } else { fmt.Printf("Failed: %s (Status: %d)\n", url, resp.StatusCode) } } } func prepareCheck(nodeURL string, ports []string, proxyNameList []string, wg *sync.WaitGroup) { for _, port := range ports { proxyURL := fmt.Sprintf("%s:%s", nodeURL, port) for _, proxy := range proxyNameList { url := fmt.Sprintf("%s/api/proxies/%s/delay?timeout=5000&url=http://www.gstatic.com/generate_204", proxyURL, proxy) wg.Add(1) go check(url, wg) } } } func loadNodesDetails(nodes map[string][]string) { var wg sync.WaitGroup for nodeURL, ports := range nodes { clashToolURL := fmt.Sprintf("%s:%s", nodeURL, ports[0]) url := fmt.Sprintf("%s/api/proxies", clashToolURL) resp, err := http.Get(url) if err != nil { fmt.Printf("Error: %s - %s\n", url, err) continue } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { fmt.Printf("Failed to load proxies from %s (Status: %d)\n", url, resp.StatusCode) continue } body, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Printf("Error reading response body: %s\n", err) continue } var proxies ProxiesResponse if err := json.Unmarshal(body, &proxies); err != nil { fmt.Printf("Error unmarshalling JSON: %s\n", err) continue } proxyNameList := make([]string, 0, len(proxies.Proxies)) for key := range proxies.Proxies { proxyNameList = append(proxyNameList, key) } prepareCheck(nodeURL, ports, proxyNameList, &wg) } wg.Wait() } func main() { nodes := map[string][]string{ "http://192.168.31.194": {"58001", "58002", "58003", "58004", "58005", "58006", "58007", "58008", "58009", "58010"}, "http://192.168.31.201": {"32001", "32002", "32003", "32004", "32005", "32006", "32007", "32008", "32009", "32010", "32011", "32012"}, } loadNodesDetails(nodes) fmt.Println("All done!") }