Skip to content

Commit

Permalink
Merge pull request #77 from humio/danielamkaer/reuse-httpclient
Browse files Browse the repository at this point in the history
Re-use http.Transport across requests
  • Loading branch information
SaaldjorMike authored Jun 29, 2021
2 parents 5ac224d + f31885d commit d6c2a11
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 51 deletions.
4 changes: 4 additions & 0 deletions api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const defaultUserAgent = "Humio-go-client/unknown"

type Client struct {
config Config
httpTransport *http.Transport
}

type Config struct {
Expand Down Expand Up @@ -64,8 +65,11 @@ func NewClient(config Config) *Client {
config.UserAgent = defaultUserAgent
}

httpTransport := newHttpTransport(config)

return &Client{
config: config,
httpTransport: httpTransport,
}
}

Expand Down
95 changes: 44 additions & 51 deletions api/httpclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ type headerTransport struct {
headers map[string]string
}

// NewHTTPClientWithHeaders returns a *http.Client that attaches a defined set of Headers to all requests.
// If specified, the client will also trust the CA certificate specified in the client configuration.
func (c *Client) newHTTPClientWithHeaders(headers map[string]string) *http.Client {
dialContext := c.config.DialContext
func newHttpTransport(config Config) *http.Transport {
dialContext := config.DialContext
if dialContext == nil {
dialContext = (&net.Dialer{
Timeout: 30 * time.Second,
Expand All @@ -28,65 +26,60 @@ func (c *Client) newHTTPClientWithHeaders(headers map[string]string) *http.Clien
}).DialContext
}

if c.config.Insecure {
// Return HTTP client where we skip certificate verification
return &http.Client{
Transport: &headerTransport{
base: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: dialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,

TLSClientConfig: &tls.Config{
InsecureSkipVerify: c.config.Insecure,
},
},
headers: headers,
if config.Insecure {
// Return HTTP transport where we skip certificate verification
return &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: dialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,

TLSClientConfig: &tls.Config{
InsecureSkipVerify: config.Insecure,
},
}
}

if len(c.config.CACertificatePEM) > 0 {
// Create a certificate pool and return a HTTP client with the specified specified CA certificate.
if len(config.CACertificatePEM) > 0 {
// Create a certificate pool and return a HTTP transport with the specified specified CA certificate.
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM([]byte(c.config.CACertificatePEM))
return &http.Client{
Transport: &headerTransport{
base: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: dialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,

TLSClientConfig: &tls.Config{
RootCAs: caCertPool,
InsecureSkipVerify: c.config.Insecure,
},
},
headers: headers,
caCertPool.AppendCertsFromPEM([]byte(config.CACertificatePEM))
return &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: dialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,

TLSClientConfig: &tls.Config{
RootCAs: caCertPool,
InsecureSkipVerify: config.Insecure,
},
}
}

// Return a regular default HTTP client
return &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: dialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
}

// NewHTTPClientWithHeaders returns a *http.Client that attaches a defined set of Headers to all requests.
func (c *Client) newHTTPClientWithHeaders(headers map[string]string) *http.Client {
return &http.Client{
Transport: &headerTransport{
base: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: dialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
},
base: c.httpTransport,
headers: headers,
},
}
Expand Down

0 comments on commit d6c2a11

Please sign in to comment.