diff --git a/internal/api/diagnostics.go b/internal/api/diagnostics.go index f1f4581cd..72d0f2af7 100644 --- a/internal/api/diagnostics.go +++ b/internal/api/diagnostics.go @@ -226,11 +226,7 @@ func (r *Router) handleDiagnostics(w http.ResponseWriter, req *http.Request) { Host: pbsNode.Host, } - // Test connection with a shorter timeout for PBS specifically - // PBS can be slow to respond, so we use a separate 30-second timeout - pbsCtx, pbsCancel := context.WithTimeout(context.Background(), 30*time.Second) - defer pbsCancel() - + // Test connection testCfg := pbs.ClientConfig{ Host: pbsNode.Host, User: pbsNode.User, @@ -239,7 +235,6 @@ func (r *Router) handleDiagnostics(w http.ResponseWriter, req *http.Request) { TokenValue: pbsNode.TokenValue, Fingerprint: pbsNode.Fingerprint, VerifySSL: pbsNode.VerifySSL, - Timeout: 30 * time.Second, // Set explicit timeout in client config } client, err := pbs.NewClient(testCfg) @@ -247,8 +242,8 @@ func (r *Router) handleDiagnostics(w http.ResponseWriter, req *http.Request) { pbsDiag.Connected = false pbsDiag.Error = err.Error() } else { - // Try to get version with PBS-specific context - if version, err := client.GetVersion(pbsCtx); err != nil { + // Try to get version + if version, err := client.GetVersion(ctx); err != nil { pbsDiag.Connected = false pbsDiag.Error = "Connection established but version check failed: " + err.Error() } else { diff --git a/pkg/tlsutil/fingerprint.go b/pkg/tlsutil/fingerprint.go index 53c68183b..f6ac0c49b 100644 --- a/pkg/tlsutil/fingerprint.go +++ b/pkg/tlsutil/fingerprint.go @@ -6,6 +6,7 @@ import ( "crypto/x509" "encoding/hex" "fmt" + "net" "net/http" "strings" "time" @@ -52,6 +53,15 @@ func CreateHTTPClientWithTimeout(verifySSL bool, fingerprint string, timeout tim MaxConnsPerHost: 20, // Limit concurrent connections per host IdleConnTimeout: 90 * time.Second, DisableCompression: true, // Disable compression for lower latency + // Add specific timeouts for DNS, TLS handshake, and response headers + // These prevent hanging on DNS resolution or TLS negotiation + DialContext: (&net.Dialer{ + Timeout: 10 * time.Second, // Connection timeout + KeepAlive: 30 * time.Second, + }).DialContext, + TLSHandshakeTimeout: 10 * time.Second, // TLS handshake timeout + ResponseHeaderTimeout: 10 * time.Second, // Time to wait for response headers + ExpectContinueTimeout: 1 * time.Second, } if !verifySSL && fingerprint == "" {