Make the API client's httpClient more pluggable (#2926)

This commit is contained in:
Kyle Havlovitz 2017-04-18 16:39:23 -07:00 committed by GitHub
parent e97574fc4c
commit bd9b0b34b2
2 changed files with 34 additions and 15 deletions

View File

@ -168,6 +168,9 @@ type Config struct {
// Datacenter to use. If not provided, the default agent datacenter is used. // Datacenter to use. If not provided, the default agent datacenter is used.
Datacenter string Datacenter string
// Transport is the Transport to use for the http client.
Transport *http.Transport
// HttpClient is the client to use. Default will be // HttpClient is the client to use. Default will be
// used if not provided. // used if not provided.
HttpClient *http.Client HttpClient *http.Client
@ -239,9 +242,7 @@ func defaultConfig(transportFn func() *http.Transport) *Config {
config := &Config{ config := &Config{
Address: "127.0.0.1:8500", Address: "127.0.0.1:8500",
Scheme: "http", Scheme: "http",
HttpClient: &http.Client{ Transport: transportFn(),
Transport: transportFn(),
},
} }
if addr := os.Getenv(HTTPAddrEnvName); addr != "" { if addr := os.Getenv(HTTPAddrEnvName); addr != "" {
@ -364,6 +365,10 @@ func NewClient(config *Config) (*Client, error) {
config.Scheme = defConfig.Scheme config.Scheme = defConfig.Scheme
} }
if config.Transport == nil {
config.Transport = defConfig.Transport
}
if config.HttpClient == nil { if config.HttpClient == nil {
config.HttpClient = defConfig.HttpClient config.HttpClient = defConfig.HttpClient
} }
@ -392,17 +397,14 @@ func NewClient(config *Config) (*Client, error) {
config.TLSConfig.InsecureSkipVerify = defConfig.TLSConfig.InsecureSkipVerify config.TLSConfig.InsecureSkipVerify = defConfig.TLSConfig.InsecureSkipVerify
} }
tlsClientConfig, err := SetupTLSConfig(&config.TLSConfig) if config.HttpClient == nil {
var err error
// We don't expect this to fail given that we aren't config.HttpClient, err = NewHttpClient(config.Transport, config.TLSConfig)
// parsing any of the input, but we panic just in case if err != nil {
// since this doesn't have an error return. return nil, err
if err != nil { }
return nil, err
} }
config.HttpClient.Transport.(*http.Transport).TLSClientConfig = tlsClientConfig
parts := strings.SplitN(config.Address, "://", 2) parts := strings.SplitN(config.Address, "://", 2)
if len(parts) == 2 { if len(parts) == 2 {
switch parts[0] { switch parts[0] {
@ -429,6 +431,23 @@ func NewClient(config *Config) (*Client, error) {
return client, nil return client, nil
} }
// NewHttpClient returns an http client configured with the given Transport and TLS
// config.
func NewHttpClient(transport *http.Transport, tlsConf TLSConfig) (*http.Client, error) {
tlsClientConfig, err := SetupTLSConfig(&tlsConf)
if err != nil {
return nil, err
}
transport.TLSClientConfig = tlsClientConfig
client := &http.Client{
Transport: transport,
}
return client, nil
}
// request is used to help build up a request // request is used to help build up a request
type request struct { type request struct {
config *Config config *Config

View File

@ -10,11 +10,11 @@ import (
"path/filepath" "path/filepath"
"reflect" "reflect"
"runtime" "runtime"
"strings"
"testing" "testing"
"time" "time"
"github.com/hashicorp/consul/testutil" "github.com/hashicorp/consul/testutil"
"strings"
) )
type configCallback func(c *Config) type configCallback func(c *Config)
@ -140,11 +140,11 @@ func TestDefaultConfig_env(t *testing.T) {
// Use keep alives as a check for whether pooling is on or off. // Use keep alives as a check for whether pooling is on or off.
if pooled := i == 0; pooled { if pooled := i == 0; pooled {
if config.HttpClient.Transport.(*http.Transport).DisableKeepAlives != false { if config.Transport.DisableKeepAlives != false {
t.Errorf("expected keep alives to be enabled") t.Errorf("expected keep alives to be enabled")
} }
} else { } else {
if config.HttpClient.Transport.(*http.Transport).DisableKeepAlives != true { if config.Transport.DisableKeepAlives != true {
t.Errorf("expected keep alives to be disabled") t.Errorf("expected keep alives to be disabled")
} }
} }