diff --git a/cleanhttp.go b/cleanhttp.go index 20d1c0a..68567bf 100644 --- a/cleanhttp.go +++ b/cleanhttp.go @@ -13,7 +13,7 @@ import ( // DefaultTransport returns a new http.Transport with similar default values to // http.DefaultTransport, but with idle connections and keepalives disabled. func DefaultTransport() *http.Transport { - transport := DefaultPooledTransport() + transport := DefaultPooledTransportWithMin(0) transport.DisableKeepAlives = true transport.MaxIdleConnsPerHost = -1 return transport @@ -24,6 +24,14 @@ func DefaultTransport() *http.Transport { // it can leak file descriptors over time. Only use this for transports that // will be re-used for the same host(s). func DefaultPooledTransport() *http.Transport { + return DefaultPooledTransportWithMin(0) +} + +// DefaultPooledTransportWithMin returns a new http.Transport with a minimum +// value for MaxIdleConnsPerHost. Do not use this for transient transports as +// it can leak file descriptors over time. Only use this for transports that +// will be re-used for the same host(s). +func DefaultPooledTransportWithMin(minIdleConnsPerHost int) *http.Transport { transport := &http.Transport{ Proxy: http.ProxyFromEnvironment, DialContext: (&net.Dialer{ @@ -36,7 +44,13 @@ func DefaultPooledTransport() *http.Transport { TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, ForceAttemptHTTP2: true, - MaxIdleConnsPerHost: runtime.GOMAXPROCS(0) + 1, + MaxIdleConnsPerHost: func() int { + maxIdleConnsPerHost := runtime.GOMAXPROCS(0) + 1 + if maxIdleConnsPerHost < minIdleConnsPerHost { + return minIdleConnsPerHost + } + return maxIdleConnsPerHost + }(), } return transport } @@ -55,7 +69,15 @@ func DefaultClient() *http.Client { // transient clients as it can leak file descriptors over time. Only use this // for clients that will be re-used for the same host(s). func DefaultPooledClient() *http.Client { + return DefaultPooledClientWithMin(0) +} + +// DefaultPooledClient returns a new http.Client with similar default values to +// http.Client, but with a shared Transport and minimum value for MaxIdleConnsPerHost. +// Do not use this function for transient clients as it can leak file descriptors +// over time. Only use this for clients that will be re-used for the same host(s). +func DefaultPooledClientWithMin(minIdleConnsPerHost int) *http.Client { return &http.Client{ - Transport: DefaultPooledTransport(), + Transport: DefaultPooledTransportWithMin(minIdleConnsPerHost), } }