package netcheck import ( "context" "fmt" "net" "net/url" "strings" "time" "vpnclient/internal/protocols/naive" ) // Result is a TCP reachability measurement to a proxy host. type Result struct { Name string `json:"name"` Host string `json:"host"` Port string `json:"port"` Ms int64 `json:"ms"` OK bool `json:"ok"` Error string `json:"error,omitempty"` } // PingProxyURI measures TCP connect time to the host in a naive share/proxy URI. func PingProxyURI(ctx context.Context, name, proxyURI string) Result { res := Result{Name: name} if strings.TrimSpace(proxyURI) == "" { res.Error = "нет ссылки сервера" return res } normalized, err := naive.NormalizeProxyURI(proxyURI) if err != nil { res.Error = err.Error() return res } u, err := url.Parse(normalized) if err != nil { res.Error = err.Error() return res } host := u.Hostname() port := u.Port() if port == "" { switch strings.ToLower(u.Scheme) { case "https", "quic": port = "443" default: port = "80" } } res.Host = host res.Port = port if host == "" { res.Error = "нет хоста" return res } d := net.Dialer{Timeout: 4 * time.Second} start := time.Now() conn, err := d.DialContext(ctx, "tcp", net.JoinHostPort(host, port)) if err != nil { res.Error = fmt.Sprintf("недоступен: %v", err) return res } _ = conn.Close() res.Ms = time.Since(start).Milliseconds() res.OK = true return res }