Skip to content

Commit 6a9c79c

Browse files
committed
Move HTTP keepalive and HTTP2 options to functional options
Signed-off-by: Marco Pracucci <[email protected]>
1 parent 50bd6ae commit 6a9c79c

File tree

2 files changed

+43
-19
lines changed

2 files changed

+43
-19
lines changed

config/http_config.go

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ var DefaultHTTPClientConfig = HTTPClientConfig{
4040
FollowRedirects: true,
4141
}
4242

43+
// defaultHTTPClientOptions holds the default HTTP client options.
44+
var defaultHTTPClientOptions = httpClientOptions{
45+
keepAlivesEnabled: true,
46+
http2Enabled: true,
47+
}
48+
4349
type closeIdler interface {
4450
CloseIdleConnections()
4551
}
@@ -201,7 +207,9 @@ func (a *BasicAuth) UnmarshalYAML(unmarshal func(interface{}) error) error {
201207
type DialContextFunc func(context.Context, string, string) (net.Conn, error)
202208

203209
type httpClientOptions struct {
204-
dialContextFunc DialContextFunc
210+
dialContextFunc DialContextFunc
211+
keepAlivesEnabled bool
212+
http2Enabled bool
205213
}
206214

207215
// HTTPClientOption defines an option that can be applied to the HTTP client.
@@ -214,15 +222,30 @@ func WithDialContextFunc(fn DialContextFunc) HTTPClientOption {
214222
}
215223
}
216224

225+
// WithKeepAlivesDisabled allows to disable HTTP keepalive.
226+
func WithKeepAlivesDisabled() HTTPClientOption {
227+
return func(opts *httpClientOptions) {
228+
opts.keepAlivesEnabled = false
229+
}
230+
}
231+
232+
// WithHTTP2Disabled allows to disable HTTP2.
233+
func WithHTTP2Disabled() HTTPClientOption {
234+
return func(opts *httpClientOptions) {
235+
opts.http2Enabled = false
236+
}
237+
}
238+
217239
// NewClient returns a http.Client using the specified http.RoundTripper.
218240
func newClient(rt http.RoundTripper) *http.Client {
219241
return &http.Client{Transport: rt}
220242
}
221243

222244
// NewClientFromConfig returns a new HTTP client configured for the
223-
// given config.HTTPClientConfig. The name is used as go-conntrack metric label.
224-
func NewClientFromConfig(cfg HTTPClientConfig, name string, disableKeepAlives, enableHTTP2 bool, optFuncs ...HTTPClientOption) (*http.Client, error) {
225-
rt, err := NewRoundTripperFromConfig(cfg, name, disableKeepAlives, enableHTTP2, optFuncs...)
245+
// given config.HTTPClientConfig and config.HTTPClientOption.
246+
// The name is used as go-conntrack metric label.
247+
func NewClientFromConfig(cfg HTTPClientConfig, name string, optFuncs ...HTTPClientOption) (*http.Client, error) {
248+
rt, err := NewRoundTripperFromConfig(cfg, name, optFuncs...)
226249
if err != nil {
227250
return nil, err
228251
}
@@ -236,11 +259,12 @@ func NewClientFromConfig(cfg HTTPClientConfig, name string, disableKeepAlives, e
236259
}
237260

238261
// NewRoundTripperFromConfig returns a new HTTP RoundTripper configured for the
239-
// given config.HTTPClientConfig. The name is used as go-conntrack metric label.
240-
func NewRoundTripperFromConfig(cfg HTTPClientConfig, name string, disableKeepAlives, enableHTTP2 bool, optFuncs ...HTTPClientOption) (http.RoundTripper, error) {
241-
opts := &httpClientOptions{}
262+
// given config.HTTPClientConfig and config.HTTPClientOption.
263+
// The name is used as go-conntrack metric label.
264+
func NewRoundTripperFromConfig(cfg HTTPClientConfig, name string, optFuncs ...HTTPClientOption) (http.RoundTripper, error) {
265+
opts := defaultHTTPClientOptions
242266
for _, f := range optFuncs {
243-
f(opts)
267+
f(&opts)
244268
}
245269

246270
var dialContext func(ctx context.Context, network, addr string) (net.Conn, error)
@@ -263,7 +287,7 @@ func NewRoundTripperFromConfig(cfg HTTPClientConfig, name string, disableKeepAli
263287
Proxy: http.ProxyURL(cfg.ProxyURL.URL),
264288
MaxIdleConns: 20000,
265289
MaxIdleConnsPerHost: 1000, // see https://github.com/golang/go/issues/13801
266-
DisableKeepAlives: disableKeepAlives,
290+
DisableKeepAlives: !opts.keepAlivesEnabled,
267291
TLSClientConfig: tlsConfig,
268292
DisableCompression: true,
269293
// 5 minutes is typically above the maximum sane scrape interval. So we can
@@ -273,7 +297,7 @@ func NewRoundTripperFromConfig(cfg HTTPClientConfig, name string, disableKeepAli
273297
ExpectContinueTimeout: 1 * time.Second,
274298
DialContext: dialContext,
275299
}
276-
if enableHTTP2 {
300+
if opts.http2Enabled {
277301
// HTTP/2 support is golang has many problematic cornercases where
278302
// dead connections would be kept and used in connection pools.
279303
// https://github.com/golang/go/issues/32388

config/http_config_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ func TestNewClientFromConfig(t *testing.T) {
354354
if err != nil {
355355
t.Fatal(err.Error())
356356
}
357-
client, err := NewClientFromConfig(validConfig.clientConfig, "test", false, true)
357+
client, err := NewClientFromConfig(validConfig.clientConfig, "test")
358358
if err != nil {
359359
t.Errorf("Can't create a client from this config: %+v", validConfig.clientConfig)
360360
continue
@@ -404,7 +404,7 @@ func TestNewClientFromInvalidConfig(t *testing.T) {
404404
}
405405

406406
for _, invalidConfig := range newClientInvalidConfig {
407-
client, err := NewClientFromConfig(invalidConfig.clientConfig, "test", false, true)
407+
client, err := NewClientFromConfig(invalidConfig.clientConfig, "test")
408408
if client != nil {
409409
t.Errorf("A client instance was returned instead of nil using this config: %+v", invalidConfig.clientConfig)
410410
}
@@ -423,7 +423,7 @@ func TestCustomDialContextFunc(t *testing.T) {
423423
}
424424

425425
cfg := HTTPClientConfig{}
426-
client, err := NewClientFromConfig(cfg, "test", false, true, WithDialContextFunc(dialFn))
426+
client, err := NewClientFromConfig(cfg, "test", WithDialContextFunc(dialFn))
427427
if err != nil {
428428
t.Fatalf("Can't create a client from this config: %+v", cfg)
429429
}
@@ -460,7 +460,7 @@ func TestMissingBearerAuthFile(t *testing.T) {
460460
}
461461
defer testServer.Close()
462462

463-
client, err := NewClientFromConfig(cfg, "test", false, true)
463+
client, err := NewClientFromConfig(cfg, "test")
464464
if err != nil {
465465
t.Fatal(err)
466466
}
@@ -658,7 +658,7 @@ func TestBasicAuthNoPassword(t *testing.T) {
658658
if err != nil {
659659
t.Fatalf("Error loading HTTP client config: %v", err)
660660
}
661-
client, err := NewClientFromConfig(*cfg, "test", false, true)
661+
client, err := NewClientFromConfig(*cfg, "test")
662662
if err != nil {
663663
t.Fatalf("Error creating HTTP Client: %v", err)
664664
}
@@ -684,7 +684,7 @@ func TestBasicAuthNoUsername(t *testing.T) {
684684
if err != nil {
685685
t.Fatalf("Error loading HTTP client config: %v", err)
686686
}
687-
client, err := NewClientFromConfig(*cfg, "test", false, true)
687+
client, err := NewClientFromConfig(*cfg, "test")
688688
if err != nil {
689689
t.Fatalf("Error creating HTTP Client: %v", err)
690690
}
@@ -710,7 +710,7 @@ func TestBasicAuthPasswordFile(t *testing.T) {
710710
if err != nil {
711711
t.Fatalf("Error loading HTTP client config: %v", err)
712712
}
713-
client, err := NewClientFromConfig(*cfg, "test", false, true)
713+
client, err := NewClientFromConfig(*cfg, "test")
714714
if err != nil {
715715
t.Fatalf("Error creating HTTP Client: %v", err)
716716
}
@@ -861,7 +861,7 @@ func TestTLSRoundTripper(t *testing.T) {
861861
writeCertificate(bs, tc.cert, cert)
862862
writeCertificate(bs, tc.key, key)
863863
if c == nil {
864-
c, err = NewClientFromConfig(cfg, "test", false, true)
864+
c, err = NewClientFromConfig(cfg, "test")
865865
if err != nil {
866866
t.Fatalf("Error creating HTTP Client: %v", err)
867867
}
@@ -933,7 +933,7 @@ func TestTLSRoundTripperRaces(t *testing.T) {
933933
writeCertificate(bs, TLSCAChainPath, ca)
934934
writeCertificate(bs, ClientCertificatePath, cert)
935935
writeCertificate(bs, ClientKeyNoPassPath, key)
936-
c, err = NewClientFromConfig(cfg, "test", false, true)
936+
c, err = NewClientFromConfig(cfg, "test")
937937
if err != nil {
938938
t.Fatalf("Error creating HTTP Client: %v", err)
939939
}

0 commit comments

Comments
 (0)