diff --git a/api/api.go b/api/api.go index 6736aecd2e..51b73b4830 100644 --- a/api/api.go +++ b/api/api.go @@ -13,6 +13,7 @@ import ( "os" "strconv" "strings" + "sync" "time" "github.com/hashicorp/go-cleanhttp" @@ -122,12 +123,20 @@ type Config struct { Token string } +var defaultHttpClient = cleanhttp.DefaultClient() + +var defaultInsecureTransport = &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, +} + // DefaultConfig returns a default configuration for the client func DefaultConfig() *Config { config := &Config{ Address: "127.0.0.1:8500", Scheme: "http", - HttpClient: cleanhttp.DefaultClient(), + HttpClient: defaultHttpClient, } if addr := os.Getenv("CONSUL_HTTP_ADDR"); addr != "" { @@ -172,11 +181,7 @@ func DefaultConfig() *Config { } if !doVerify { - config.HttpClient.Transport = &http.Transport{ - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: true, - }, - } + config.HttpClient.Transport = defaultInsecureTransport } } @@ -188,6 +193,9 @@ type Client struct { config Config } +var unixClients = make(map[string]*http.Client) +var unixClientsLock sync.Mutex + // NewClient returns a new client func NewClient(config *Config) (*Client, error) { // bootstrap the config @@ -206,14 +214,22 @@ func NewClient(config *Config) (*Client, error) { } if parts := strings.SplitN(config.Address, "unix://", 2); len(parts) == 2 { - trans := cleanhttp.DefaultTransport() - trans.Dial = func(_, _ string) (net.Conn, error) { - return net.Dial("unix", parts[1]) - } - config.HttpClient = &http.Client{ - Transport: trans, - } config.Address = parts[1] + + unixClientsLock.Lock() + if client, ok := unixClients[config.Address]; ok { + config.HttpClient = client + } else { + trans := cleanhttp.DefaultTransport() + trans.Dial = func(_, _ string) (net.Conn, error) { + return net.Dial("unix", config.Address) + } + config.HttpClient = &http.Client{ + Transport: trans, + } + unixClients[config.Address] = config.HttpClient + } + unixClientsLock.Unlock() } client := &Client{ diff --git a/api/api_test.go b/api/api_test.go index 314a89b146..4f13d0ae2c 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -244,13 +244,16 @@ func TestAPI_UnixSocket(t *testing.T) { }) defer s.Stop() - agent := c.Agent() - - info, err := agent.Self() - if err != nil { - t.Fatalf("err: %s", err) - } - if info["Config"]["NodeName"] == "" { - t.Fatalf("bad: %v", info) + // Run a few iterations to test the path where we use the pooled + // connection. + for i := 0; i < 3; i++ { + agent := c.Agent() + info, err := agent.Self() + if err != nil { + t.Fatalf("err: %s", err) + } + if info["Config"]["NodeName"] == "" { + t.Fatalf("bad: %v", info) + } } }