Skip to content

Instantly share code, notes, and snippets.

@RussellLuo
Created May 27, 2020 08:16
Show Gist options
  • Save RussellLuo/b9a552a5782fdc96940db89dcdb985ee to your computer and use it in GitHub Desktop.
Save RussellLuo/b9a552a5782fdc96940db89dcdb985ee to your computer and use it in GitHub Desktop.
An HTTP client creator for Golang
package httpclient
import (
"net"
"net/http"
"time"
)
// Options includes common Client configurations that need to be tuned.
type Options struct {
TotalTimeout time.Duration
ConnectTimeout time.Duration
KeepAliveTimeout time.Duration
MaxIdleConns int
MaxIdleConnsPerHost int
IdleConnTimeout time.Duration
TLSHandshakeTimeout time.Duration
ResponseHeaderTimeout time.Duration
ExpectContinueTimeout time.Duration
}
func (o *Options) totalTimeout() time.Duration {
if o == nil {
return 30 * time.Second
}
return o.TotalTimeout
}
func (o *Options) connectTimeout() time.Duration {
if o == nil {
return 30 * time.Second
}
return o.ConnectTimeout
}
func (o *Options) keepAliveTimeout() time.Duration {
if o == nil {
return 30 * time.Second
}
return o.KeepAliveTimeout
}
func (o *Options) maxIdleConns() int {
if o == nil {
return 100
}
return o.MaxIdleConns
}
func (o *Options) maxIdleConnsPerHost() int {
if o == nil {
return 0
}
return o.MaxIdleConnsPerHost
}
func (o *Options) idleConnTimeout() time.Duration {
if o == nil {
return 90 * time.Second
}
return o.IdleConnTimeout
}
func (o *Options) tlsHandshakeTimeout() time.Duration {
if o == nil {
return 10 * time.Second
}
return o.TLSHandshakeTimeout
}
func (o *Options) responseHeaderTimeout() time.Duration {
if o == nil {
return 0
}
return o.ResponseHeaderTimeout
}
func (o *Options) expectContinueTimeout() time.Duration {
if o == nil {
return 1 * time.Second
}
return o.ExpectContinueTimeout
}
// New creates a Client with the given options. If nil is provided, the created
// Client will behave like the default Client with Timeout set to 30s.
func New(opts *Options) *http.Client {
transport := &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: opts.connectTimeout(),
KeepAlive: opts.keepAliveTimeout(),
DualStack: true,
}).DialContext,
MaxIdleConns: opts.maxIdleConns(),
MaxIdleConnsPerHost: opts.maxIdleConnsPerHost(),
IdleConnTimeout: opts.idleConnTimeout(),
TLSHandshakeTimeout: opts.tlsHandshakeTimeout(),
ResponseHeaderTimeout: opts.responseHeaderTimeout(),
ExpectContinueTimeout: opts.expectContinueTimeout(),
}
return &http.Client{
Timeout: opts.totalTimeout(),
Transport: transport,
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment