NewRoundTripperFromConfig returns a new HTTP RoundTripper configured for the given config.HTTPClientConfig and config.HTTPClientOption. The name is used as go-conntrack metric label.
(cfg HTTPClientConfig, name string, optFuncs ...HTTPClientOption)
| 496 | // given config.HTTPClientConfig and config.HTTPClientOption. |
| 497 | // The name is used as go-conntrack metric label. |
| 498 | func NewRoundTripperFromConfig(cfg HTTPClientConfig, name string, optFuncs ...HTTPClientOption) (http.RoundTripper, error) { |
| 499 | opts := defaultHTTPClientOptions |
| 500 | for _, f := range optFuncs { |
| 501 | f(&opts) |
| 502 | } |
| 503 | |
| 504 | var dialContext func(ctx context.Context, network, addr string) (net.Conn, error) |
| 505 | |
| 506 | if opts.dialContextFunc != nil { |
| 507 | dialContext = conntrack.NewDialContextFunc( |
| 508 | conntrack.DialWithDialContextFunc((func(context.Context, string, string) (net.Conn, error))(opts.dialContextFunc)), |
| 509 | conntrack.DialWithTracing(), |
| 510 | conntrack.DialWithName(name)) |
| 511 | } else { |
| 512 | dialContext = conntrack.NewDialContextFunc( |
| 513 | conntrack.DialWithTracing(), |
| 514 | conntrack.DialWithName(name)) |
| 515 | } |
| 516 | |
| 517 | newRT := func(tlsConfig *tls.Config) (http.RoundTripper, error) { |
| 518 | // The only timeout we care about is the configured scrape timeout. |
| 519 | // It is applied on request. So we leave out any timings here. |
| 520 | var rt http.RoundTripper = &http.Transport{ |
| 521 | Proxy: cfg.ProxyConfig.Proxy(), |
| 522 | ProxyConnectHeader: cfg.ProxyConfig.GetProxyConnectHeader(), |
| 523 | MaxIdleConns: 20000, |
| 524 | MaxIdleConnsPerHost: 1000, // see https://github.com/golang/go/issues/13801 |
| 525 | DisableKeepAlives: !opts.keepAlivesEnabled, |
| 526 | TLSClientConfig: tlsConfig, |
| 527 | DisableCompression: true, |
| 528 | IdleConnTimeout: opts.idleConnTimeout, |
| 529 | TLSHandshakeTimeout: 10 * time.Second, |
| 530 | ExpectContinueTimeout: 1 * time.Second, |
| 531 | DialContext: dialContext, |
| 532 | } |
| 533 | if opts.http2Enabled && cfg.EnableHTTP2 { |
| 534 | // HTTP/2 support is golang had many problematic cornercases where |
| 535 | // dead connections would be kept and used in connection pools. |
| 536 | // https://github.com/golang/go/issues/32388 |
| 537 | // https://github.com/golang/go/issues/39337 |
| 538 | // https://github.com/golang/go/issues/39750 |
| 539 | |
| 540 | http2t, err := http2.ConfigureTransports(rt.(*http.Transport)) |
| 541 | if err != nil { |
| 542 | return nil, err |
| 543 | } |
| 544 | http2t.ReadIdleTimeout = time.Minute |
| 545 | } |
| 546 | |
| 547 | // If a authorization_credentials is provided, create a round tripper that will set the |
| 548 | // Authorization header correctly on each request. |
| 549 | if cfg.Authorization != nil && len(cfg.Authorization.CredentialsFile) > 0 { |
| 550 | rt = NewAuthorizationCredentialsFileRoundTripper(cfg.Authorization.Type, cfg.Authorization.CredentialsFile, rt) |
| 551 | } else if cfg.Authorization != nil { |
| 552 | rt = NewAuthorizationCredentialsRoundTripper(cfg.Authorization.Type, cfg.Authorization.Credentials, rt) |
| 553 | } |
| 554 | // Backwards compatibility, be nice with importers who would not have |
| 555 | // called Validate(). |