package httpclient import ( "crypto/tls" "net" "net/http" "time" ) // DefaultClient returns a production-ready HTTP client with reasonable timeouts // and connection pooling to prevent resource exhaustion func DefaultClient() *http.Client { return &http.Client{ Timeout: 30 * time.Second, Transport: &http.Transport{ // Connection pool settings MaxIdleConns: 100, MaxIdleConnsPerHost: 10, MaxConnsPerHost: 50, IdleConnTimeout: 90 * time.Second, // Timeouts DialContext: (&net.Dialer{ Timeout: 10 * time.Second, KeepAlive: 30 * time.Second, }).DialContext, TLSHandshakeTimeout: 10 * time.Second, ResponseHeaderTimeout: 15 * time.Second, ExpectContinueTimeout: 1 * time.Second, // HTTP/2 support ForceAttemptHTTP2: true, // TLS settings TLSClientConfig: &tls.Config{ MinVersion: tls.VersionTLS12, }, }, } } // FastClient returns a client optimized for fast internal API calls func FastClient() *http.Client { return &http.Client{ Timeout: 5 * time.Second, Transport: &http.Transport{ MaxIdleConns: 50, MaxIdleConnsPerHost: 10, IdleConnTimeout: 30 * time.Second, DialContext: (&net.Dialer{ Timeout: 2 * time.Second, KeepAlive: 15 * time.Second, }).DialContext, TLSHandshakeTimeout: 3 * time.Second, ResponseHeaderTimeout: 4 * time.Second, }, } } // SlowClient returns a client for potentially slow external APIs (e.g., AI, analytics) func SlowClient() *http.Client { return &http.Client{ Timeout: 60 * time.Second, Transport: &http.Transport{ MaxIdleConns: 20, MaxIdleConnsPerHost: 5, IdleConnTimeout: 120 * time.Second, DialContext: (&net.Dialer{ Timeout: 15 * time.Second, KeepAlive: 60 * time.Second, }).DialContext, TLSHandshakeTimeout: 15 * time.Second, ResponseHeaderTimeout: 30 * time.Second, }, } }