diff --git a/cmd/thanos/query_frontend.go b/cmd/thanos/query_frontend.go index b6a85d3a5d..5bebbf39c2 100644 --- a/cmd/thanos/query_frontend.go +++ b/cmd/thanos/query_frontend.go @@ -4,6 +4,7 @@ package main import ( + "net" "net/http" "time" @@ -25,7 +26,6 @@ import ( "github.com/thanos-io/thanos/pkg/api" "github.com/thanos-io/thanos/pkg/component" - "github.com/thanos-io/thanos/pkg/exthttp" "github.com/thanos-io/thanos/pkg/extkingpin" "github.com/thanos-io/thanos/pkg/extprom" extpromhttp "github.com/thanos-io/thanos/pkg/extprom/http" @@ -150,7 +150,19 @@ func registerQueryFrontend(app *extkingpin.App) { } func parseTransportConfiguration(downstreamTripperConfContentYaml []byte) (*http.Transport, error) { - downstreamTripper := exthttp.NewTransport() + downstreamTripper := &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + DualStack: true, + }).DialContext, + ForceAttemptHTTP2: true, + MaxIdleConns: 100, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + } if len(downstreamTripperConfContentYaml) > 0 { tripperConfig := &queryfrontend.DownstreamTripperConfig{} diff --git a/docs/storage.md b/docs/storage.md index b2f0316537..23529200df 100644 --- a/docs/storage.md +++ b/docs/storage.md @@ -86,6 +86,7 @@ config: key_file: "" server_name: "" insecure_skip_verify: false + disable_compression: false trace: enable: false list_objects_version: "" @@ -356,13 +357,13 @@ config: max_idle_conns: 0 max_idle_conns_per_host: 0 max_conns_per_host: 0 - disable_compression: false tls_config: ca_file: "" cert_file: "" key_file: "" server_name: "" insecure_skip_verify: false + disable_compression: false prefix: "" ``` @@ -425,11 +426,19 @@ config: http_config: idle_conn_timeout: 1m30s response_header_timeout: 2m + insecure_skip_verify: false tls_handshake_timeout: 10s expect_continue_timeout: 1s max_idle_conns: 100 max_idle_conns_per_host: 100 max_conns_per_host: 0 + tls_config: + ca_file: "" + cert_file: "" + key_file: "" + server_name: "" + insecure_skip_verify: false + disable_compression: false prefix: "" ``` diff --git a/pkg/objstore/tlsconfig.go b/pkg/exthttp/tlsconfig.go similarity index 99% rename from pkg/objstore/tlsconfig.go rename to pkg/exthttp/tlsconfig.go index f705fa31b6..d1315ad285 100644 --- a/pkg/objstore/tlsconfig.go +++ b/pkg/exthttp/tlsconfig.go @@ -1,7 +1,7 @@ // Copyright (c) The Thanos Authors. // Licensed under the Apache License 2.0. -package objstore +package exthttp import ( "crypto/tls" @@ -10,6 +10,20 @@ import ( "io/ioutil" ) +// TLSConfig configures the options for TLS connections. +type TLSConfig struct { + // The CA cert to use for the targets. + CAFile string `yaml:"ca_file"` + // The client cert file for the targets. + CertFile string `yaml:"cert_file"` + // The client key file for the targets. + KeyFile string `yaml:"key_file"` + // Used to verify the hostname for the targets. + ServerName string `yaml:"server_name"` + // Disable target certificate validation. + InsecureSkipVerify bool `yaml:"insecure_skip_verify"` +} + // NewTLSConfig creates a new tls.Config from the given TLSConfig. func NewTLSConfig(cfg *TLSConfig) (*tls.Config, error) { tlsConfig := &tls.Config{InsecureSkipVerify: cfg.InsecureSkipVerify} @@ -71,17 +85,3 @@ func (c *TLSConfig) getClientCertificate(*tls.CertificateRequestInfo) (*tls.Cert } return &cert, nil } - -// TLSConfig configures the options for TLS connections. -type TLSConfig struct { - // The CA cert to use for the targets. - CAFile string `yaml:"ca_file"` - // The client cert file for the targets. - CertFile string `yaml:"cert_file"` - // The client key file for the targets. - KeyFile string `yaml:"key_file"` - // Used to verify the hostname for the targets. - ServerName string `yaml:"server_name"` - // Disable target certificate validation. - InsecureSkipVerify bool `yaml:"insecure_skip_verify"` -} diff --git a/pkg/exthttp/transport.go b/pkg/exthttp/transport.go index 60e82e2cc8..76d6ee70d4 100644 --- a/pkg/exthttp/transport.go +++ b/pkg/exthttp/transport.go @@ -7,10 +7,40 @@ import ( "net" "net/http" "time" + + "github.com/prometheus/common/model" ) -// NewTransport creates a new http.Transport with default settings. -func NewTransport() *http.Transport { +// TODO(bwplotka): HTTPConfig stores the http.Transport configuration for the cos and s3 minio client. +type HTTPConfig struct { + IdleConnTimeout model.Duration `yaml:"idle_conn_timeout"` + ResponseHeaderTimeout model.Duration `yaml:"response_header_timeout"` + InsecureSkipVerify bool `yaml:"insecure_skip_verify"` + + TLSHandshakeTimeout model.Duration `yaml:"tls_handshake_timeout"` + ExpectContinueTimeout model.Duration `yaml:"expect_continue_timeout"` + MaxIdleConns int `yaml:"max_idle_conns"` + MaxIdleConnsPerHost int `yaml:"max_idle_conns_per_host"` + MaxConnsPerHost int `yaml:"max_conns_per_host"` + + // Transport field allows upstream callers to inject a custom round tripper. + Transport http.RoundTripper `yaml:"-"` + + TLSConfig TLSConfig `yaml:"tls_config"` + DisableCompression bool `yaml:"disable_compression"` +} + +// DefaultTransport - this default transport is based on the Minio +// DefaultTransport up until the following commit: +// https://github.com/minio/minio-go/commit/008c7aa71fc17e11bf980c209a4f8c4d687fc884 +// The values have since diverged. +func DefaultTransport(config HTTPConfig) (*http.Transport, error) { + tlsConfig, err := NewTLSConfig(&config.TLSConfig) + if err != nil { + return nil, err + } + tlsConfig.InsecureSkipVerify = config.InsecureSkipVerify + return &http.Transport{ Proxy: http.ProxyFromEnvironment, DialContext: (&net.Dialer{ @@ -18,10 +48,22 @@ func NewTransport() *http.Transport { KeepAlive: 30 * time.Second, DualStack: true, }).DialContext, - ForceAttemptHTTP2: true, - MaxIdleConns: 100, - IdleConnTimeout: 90 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, - ExpectContinueTimeout: 1 * time.Second, - } + + MaxIdleConns: config.MaxIdleConns, + MaxIdleConnsPerHost: config.MaxIdleConnsPerHost, + IdleConnTimeout: time.Duration(config.IdleConnTimeout), + MaxConnsPerHost: config.MaxConnsPerHost, + TLSHandshakeTimeout: time.Duration(config.TLSHandshakeTimeout), + ExpectContinueTimeout: time.Duration(config.ExpectContinueTimeout), + // A custom ResponseHeaderTimeout was introduced + // to cover cases where the tcp connection works but + // the server never answers. Defaults to 2 minutes. + ResponseHeaderTimeout: time.Duration(config.ResponseHeaderTimeout), + // Set this value so that the underlying transport round-tripper + // doesn't try to auto decode the body of objects with + // content-encoding set to `gzip`. + // + // Refer: https://golang.org/src/net/http/transport.go?h=roundTrip#L1843. + TLSClientConfig: tlsConfig, + }, nil } diff --git a/pkg/objstore/azure/azure.go b/pkg/objstore/azure/azure.go index f79b7df237..44530450c4 100644 --- a/pkg/objstore/azure/azure.go +++ b/pkg/objstore/azure/azure.go @@ -20,6 +20,7 @@ import ( "github.com/prometheus/common/model" "gopkg.in/yaml.v2" + "github.com/thanos-io/thanos/pkg/exthttp" "github.com/thanos-io/thanos/pkg/objstore" ) @@ -27,18 +28,9 @@ const ( azureDefaultEndpoint = "blob.core.windows.net" ) -// Set default retry values to default Azure values. 0 = use Default Azure. +// DefaultConfig for Azure objstore client. var DefaultConfig = Config{ - PipelineConfig: PipelineConfig{ - MaxTries: 0, - TryTimeout: 0, - RetryDelay: 0, - MaxRetryDelay: 0, - }, - ReaderConfig: ReaderConfig{ - MaxRetryRequests: 0, - }, - HTTPConfig: HTTPConfig{ + HTTPConfig: exthttp.HTTPConfig{ IdleConnTimeout: model.Duration(90 * time.Second), ResponseHeaderTimeout: model.Duration(2 * time.Minute), TLSHandshakeTimeout: model.Duration(10 * time.Second), @@ -52,16 +44,16 @@ var DefaultConfig = Config{ // Config Azure storage configuration. type Config struct { - StorageAccountName string `yaml:"storage_account"` - StorageAccountKey string `yaml:"storage_account_key"` - ContainerName string `yaml:"container"` - Endpoint string `yaml:"endpoint"` - MaxRetries int `yaml:"max_retries"` - MSIResource string `yaml:"msi_resource"` - UserAssignedID string `yaml:"user_assigned_id"` - PipelineConfig PipelineConfig `yaml:"pipeline_config"` - ReaderConfig ReaderConfig `yaml:"reader_config"` - HTTPConfig HTTPConfig `yaml:"http_config"` + StorageAccountName string `yaml:"storage_account"` + StorageAccountKey string `yaml:"storage_account_key"` + ContainerName string `yaml:"container"` + Endpoint string `yaml:"endpoint"` + MaxRetries int `yaml:"max_retries"` + MSIResource string `yaml:"msi_resource"` + UserAssignedID string `yaml:"user_assigned_id"` + PipelineConfig PipelineConfig `yaml:"pipeline_config"` + ReaderConfig ReaderConfig `yaml:"reader_config"` + HTTPConfig exthttp.HTTPConfig `yaml:"http_config"` } type ReaderConfig struct { @@ -75,21 +67,6 @@ type PipelineConfig struct { MaxRetryDelay model.Duration `yaml:"max_retry_delay"` } -type HTTPConfig struct { - IdleConnTimeout model.Duration `yaml:"idle_conn_timeout"` - ResponseHeaderTimeout model.Duration `yaml:"response_header_timeout"` - InsecureSkipVerify bool `yaml:"insecure_skip_verify"` - - TLSHandshakeTimeout model.Duration `yaml:"tls_handshake_timeout"` - ExpectContinueTimeout model.Duration `yaml:"expect_continue_timeout"` - MaxIdleConns int `yaml:"max_idle_conns"` - MaxIdleConnsPerHost int `yaml:"max_idle_conns_per_host"` - MaxConnsPerHost int `yaml:"max_conns_per_host"` - DisableCompression bool `yaml:"disable_compression"` - - TLSConfig objstore.TLSConfig `yaml:"tls_config"` -} - // Bucket implements the store.Bucket interface against Azure APIs. type Bucket struct { logger log.Logger @@ -152,6 +129,11 @@ func (conf *Config) validate() error { return nil } +// HTTPConfig exists here only because Cortex depends on it, and we depend on Cortex. +// Deprecated. +// TODO(bwplotka): Remove it, once we remove Cortex cycle dep, or Cortex stops using this. +type HTTPConfig = exthttp.HTTPConfig + // parseConfig unmarshals a buffer into a Config with default values. func parseConfig(conf []byte) (Config, error) { config := DefaultConfig diff --git a/pkg/objstore/azure/azure_test.go b/pkg/objstore/azure/azure_test.go index ffef1c8a0e..fcf51e0a10 100644 --- a/pkg/objstore/azure/azure_test.go +++ b/pkg/objstore/azure/azure_test.go @@ -7,6 +7,7 @@ import ( "testing" "time" + "github.com/thanos-io/thanos/pkg/exthttp" "github.com/thanos-io/thanos/pkg/testutil" ) @@ -235,7 +236,7 @@ http_config: `) cfg, err := parseConfig(input) testutil.Ok(t, err) - transport, err := DefaultTransport(cfg) + transport, err := exthttp.DefaultTransport(cfg.HTTPConfig) testutil.Ok(t, err) testutil.Equals(t, true, transport.TLSClientConfig.InsecureSkipVerify) } diff --git a/pkg/objstore/azure/helpers.go b/pkg/objstore/azure/helpers.go index 3a2e31954f..cebcd27dd4 100644 --- a/pkg/objstore/azure/helpers.go +++ b/pkg/objstore/azure/helpers.go @@ -6,7 +6,6 @@ package azure import ( "context" "fmt" - "net" "net/http" "net/url" "regexp" @@ -18,7 +17,7 @@ import ( "github.com/Azure/go-autorest/autorest/azure/auth" "github.com/go-kit/log" "github.com/go-kit/log/level" - "github.com/thanos-io/thanos/pkg/objstore" + "github.com/thanos-io/thanos/pkg/exthttp" ) // DirDelim is the delimiter used to model a directory structure in an object store bucket. @@ -104,7 +103,7 @@ func getContainerURL(ctx context.Context, logger log.Logger, conf Config) (blob. retryOptions.TryTimeout = time.Until(deadline) } - dt, err := DefaultTransport(conf) + dt, err := exthttp.DefaultTransport(conf.HTTPConfig) if err != nil { return blob.ContainerURL{}, err } @@ -140,36 +139,6 @@ func getContainerURL(ctx context.Context, logger log.Logger, conf Config) (blob. return service.NewContainerURL(conf.ContainerName), nil } -func DefaultTransport(config Config) (*http.Transport, error) { - tlsConfig, err := objstore.NewTLSConfig(&config.HTTPConfig.TLSConfig) - if err != nil { - return nil, err - } - - if config.HTTPConfig.InsecureSkipVerify { - tlsConfig.InsecureSkipVerify = true - } - return &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DialContext: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - DualStack: true, - }).DialContext, - - MaxIdleConns: config.HTTPConfig.MaxIdleConns, - MaxIdleConnsPerHost: config.HTTPConfig.MaxIdleConnsPerHost, - IdleConnTimeout: time.Duration(config.HTTPConfig.IdleConnTimeout), - MaxConnsPerHost: config.HTTPConfig.MaxConnsPerHost, - TLSHandshakeTimeout: time.Duration(config.HTTPConfig.TLSHandshakeTimeout), - ExpectContinueTimeout: time.Duration(config.HTTPConfig.ExpectContinueTimeout), - - ResponseHeaderTimeout: time.Duration(config.HTTPConfig.ResponseHeaderTimeout), - DisableCompression: config.HTTPConfig.DisableCompression, - TLSClientConfig: tlsConfig, - }, nil -} - func getContainer(ctx context.Context, logger log.Logger, conf Config) (blob.ContainerURL, error) { c, err := getContainerURL(ctx, logger, conf) if err != nil { diff --git a/pkg/objstore/cos/cos.go b/pkg/objstore/cos/cos.go index 91529db2a5..a22010bb72 100644 --- a/pkg/objstore/cos/cos.go +++ b/pkg/objstore/cos/cos.go @@ -40,7 +40,7 @@ type Bucket struct { // DefaultConfig is the default config for an cos client. default tune the `MaxIdleConnsPerHost`. var DefaultConfig = Config{ - HTTPConfig: HTTPConfig{ + HTTPConfig: exthttp.HTTPConfig{ IdleConnTimeout: model.Duration(90 * time.Second), ResponseHeaderTimeout: model.Duration(2 * time.Minute), TLSHandshakeTimeout: model.Duration(10 * time.Second), @@ -53,13 +53,13 @@ var DefaultConfig = Config{ // Config encapsulates the necessary config values to instantiate an cos client. type Config struct { - Bucket string `yaml:"bucket"` - Region string `yaml:"region"` - AppId string `yaml:"app_id"` - Endpoint string `yaml:"endpoint"` - SecretKey string `yaml:"secret_key"` - SecretId string `yaml:"secret_id"` - HTTPConfig HTTPConfig `yaml:"http_config"` + Bucket string `yaml:"bucket"` + Region string `yaml:"region"` + AppId string `yaml:"app_id"` + Endpoint string `yaml:"endpoint"` + SecretKey string `yaml:"secret_key"` + SecretId string `yaml:"secret_id"` + HTTPConfig exthttp.HTTPConfig `yaml:"http_config"` } // Validate checks to see if mandatory cos config options are set. @@ -94,30 +94,6 @@ func parseConfig(conf []byte) (Config, error) { return config, nil } -// HTTPConfig stores the http.Transport configuration for the cos client. -type HTTPConfig struct { - IdleConnTimeout model.Duration `yaml:"idle_conn_timeout"` - ResponseHeaderTimeout model.Duration `yaml:"response_header_timeout"` - TLSHandshakeTimeout model.Duration `yaml:"tls_handshake_timeout"` - ExpectContinueTimeout model.Duration `yaml:"expect_continue_timeout"` - MaxIdleConns int `yaml:"max_idle_conns"` - MaxIdleConnsPerHost int `yaml:"max_idle_conns_per_host"` - MaxConnsPerHost int `yaml:"max_conns_per_host"` -} - -// DefaultTransport build http.Transport from config. -func DefaultTransport(c HTTPConfig) *http.Transport { - transport := exthttp.NewTransport() - transport.IdleConnTimeout = time.Duration(c.IdleConnTimeout) - transport.ResponseHeaderTimeout = time.Duration(c.ResponseHeaderTimeout) - transport.TLSHandshakeTimeout = time.Duration(c.TLSHandshakeTimeout) - transport.ExpectContinueTimeout = time.Duration(c.ExpectContinueTimeout) - transport.MaxIdleConns = c.MaxIdleConns - transport.MaxIdleConnsPerHost = c.MaxIdleConnsPerHost - transport.MaxConnsPerHost = c.MaxConnsPerHost - return transport -} - // NewBucket returns a new Bucket using the provided cos configuration. func NewBucket(logger log.Logger, conf []byte, component string) (*Bucket, error) { if logger == nil { @@ -149,11 +125,12 @@ func NewBucketWithConfig(logger log.Logger, config Config, component string) (*B bucketURL = cos.NewBucketURL(fmt.Sprintf("%s-%s", config.Bucket, config.AppId), config.Region, true) } b := &cos.BaseURL{BucketURL: bucketURL} + tpt, _ := exthttp.DefaultTransport(config.HTTPConfig) client := cos.NewClient(b, &http.Client{ Transport: &cos.AuthorizationTransport{ SecretID: config.SecretId, SecretKey: config.SecretKey, - Transport: DefaultTransport(config.HTTPConfig), + Transport: tpt, }, }) diff --git a/pkg/objstore/cos/cos_test.go b/pkg/objstore/cos/cos_test.go index 12f175de1a..cc9432e97c 100644 --- a/pkg/objstore/cos/cos_test.go +++ b/pkg/objstore/cos/cos_test.go @@ -8,6 +8,7 @@ import ( "time" "github.com/prometheus/common/model" + "github.com/thanos-io/thanos/pkg/exthttp" "github.com/thanos-io/thanos/pkg/testutil" ) @@ -38,7 +39,7 @@ http_config: `), }, want: Config{ - HTTPConfig: HTTPConfig{ + HTTPConfig: exthttp.HTTPConfig{ IdleConnTimeout: model.Duration(90 * time.Second), ResponseHeaderTimeout: model.Duration(2 * time.Minute), TLSHandshakeTimeout: model.Duration(10 * time.Second), @@ -71,7 +72,7 @@ func TestConfig_validate(t *testing.T) { Endpoint string SecretKey string SecretId string - HTTPConfig HTTPConfig + HTTPConfig exthttp.HTTPConfig } tests := []struct { name string diff --git a/pkg/objstore/s3/s3.go b/pkg/objstore/s3/s3.go index 1e0ae3fe62..e8b0f80dea 100644 --- a/pkg/objstore/s3/s3.go +++ b/pkg/objstore/s3/s3.go @@ -9,7 +9,6 @@ import ( "fmt" "io" "io/ioutil" - "net" "net/http" "os" "runtime" @@ -26,10 +25,10 @@ import ( "github.com/pkg/errors" "github.com/prometheus/common/model" "github.com/prometheus/common/version" - "gopkg.in/yaml.v2" - + "github.com/thanos-io/thanos/pkg/exthttp" "github.com/thanos-io/thanos/pkg/objstore" "github.com/thanos-io/thanos/pkg/runutil" + "gopkg.in/yaml.v2" ) type ctxKey int @@ -100,7 +99,7 @@ const ( var DefaultConfig = Config{ PutUserMetadata: map[string]string{}, - HTTPConfig: HTTPConfig{ + HTTPConfig: exthttp.HTTPConfig{ IdleConnTimeout: model.Duration(90 * time.Second), ResponseHeaderTimeout: model.Duration(2 * time.Minute), TLSHandshakeTimeout: model.Duration(10 * time.Second), @@ -113,21 +112,26 @@ var DefaultConfig = Config{ BucketLookupType: AutoLookup, } +// HTTPConfig exists here only because Cortex depends on it, and we depend on Cortex. +// Deprecated. +// TODO(bwplotka): Remove it, once we remove Cortex cycle dep, or Cortex stops using this. +type HTTPConfig = exthttp.HTTPConfig + // Config stores the configuration for s3 bucket. type Config struct { - Bucket string `yaml:"bucket"` - Endpoint string `yaml:"endpoint"` - Region string `yaml:"region"` - AWSSDKAuth bool `yaml:"aws_sdk_auth"` - AccessKey string `yaml:"access_key"` - Insecure bool `yaml:"insecure"` - SignatureV2 bool `yaml:"signature_version2"` - SecretKey string `yaml:"secret_key"` - PutUserMetadata map[string]string `yaml:"put_user_metadata"` - HTTPConfig HTTPConfig `yaml:"http_config"` - TraceConfig TraceConfig `yaml:"trace"` - ListObjectsVersion string `yaml:"list_objects_version"` - BucketLookupType BucketLookupType `yaml:"bucket_lookup_type"` + Bucket string `yaml:"bucket"` + Endpoint string `yaml:"endpoint"` + Region string `yaml:"region"` + AWSSDKAuth bool `yaml:"aws_sdk_auth"` + AccessKey string `yaml:"access_key"` + Insecure bool `yaml:"insecure"` + SignatureV2 bool `yaml:"signature_version2"` + SecretKey string `yaml:"secret_key"` + PutUserMetadata map[string]string `yaml:"put_user_metadata"` + HTTPConfig exthttp.HTTPConfig `yaml:"http_config"` + TraceConfig TraceConfig `yaml:"trace"` + ListObjectsVersion string `yaml:"list_objects_version"` + BucketLookupType BucketLookupType `yaml:"bucket_lookup_type"` // PartSize used for multipart upload. Only used if uploaded object size is known and larger than configured PartSize. // NOTE we need to make sure this number does not produce more parts than 10 000. PartSize uint64 `yaml:"part_size"` @@ -148,66 +152,6 @@ type TraceConfig struct { Enable bool `yaml:"enable"` } -// HTTPConfig stores the http.Transport configuration for the s3 minio client. -type HTTPConfig struct { - IdleConnTimeout model.Duration `yaml:"idle_conn_timeout"` - ResponseHeaderTimeout model.Duration `yaml:"response_header_timeout"` - InsecureSkipVerify bool `yaml:"insecure_skip_verify"` - - TLSHandshakeTimeout model.Duration `yaml:"tls_handshake_timeout"` - ExpectContinueTimeout model.Duration `yaml:"expect_continue_timeout"` - MaxIdleConns int `yaml:"max_idle_conns"` - MaxIdleConnsPerHost int `yaml:"max_idle_conns_per_host"` - MaxConnsPerHost int `yaml:"max_conns_per_host"` - - // Allow upstream callers to inject a round tripper - Transport http.RoundTripper `yaml:"-"` - - TLSConfig objstore.TLSConfig `yaml:"tls_config"` -} - -// DefaultTransport - this default transport is based on the Minio -// DefaultTransport up until the following commit: -// https://github.com/minio/minio-go/commit/008c7aa71fc17e11bf980c209a4f8c4d687fc884 -// The values have since diverged. -func DefaultTransport(config Config) (*http.Transport, error) { - tlsConfig, err := objstore.NewTLSConfig(&config.HTTPConfig.TLSConfig) - if err != nil { - return nil, err - } - - if config.HTTPConfig.InsecureSkipVerify { - tlsConfig.InsecureSkipVerify = true - } - - return &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DialContext: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - DualStack: true, - }).DialContext, - - MaxIdleConns: config.HTTPConfig.MaxIdleConns, - MaxIdleConnsPerHost: config.HTTPConfig.MaxIdleConnsPerHost, - IdleConnTimeout: time.Duration(config.HTTPConfig.IdleConnTimeout), - MaxConnsPerHost: config.HTTPConfig.MaxConnsPerHost, - TLSHandshakeTimeout: time.Duration(config.HTTPConfig.TLSHandshakeTimeout), - ExpectContinueTimeout: time.Duration(config.HTTPConfig.ExpectContinueTimeout), - // A custom ResponseHeaderTimeout was introduced - // to cover cases where the tcp connection works but - // the server never answers. Defaults to 2 minutes. - ResponseHeaderTimeout: time.Duration(config.HTTPConfig.ResponseHeaderTimeout), - // Set this value so that the underlying transport round-tripper - // doesn't try to auto decode the body of objects with - // content-encoding set to `gzip`. - // - // Refer: https://golang.org/src/net/http/transport.go?h=roundTrip#L1843. - DisableCompression: true, - TLSClientConfig: tlsConfig, - }, nil -} - // Bucket implements the store.Bucket interface against s3-compatible APIs. type Bucket struct { logger log.Logger @@ -219,7 +163,7 @@ type Bucket struct { listObjectsV1 bool } -// parseConfig unmarshals a buffer into a Config with default HTTPConfig values. +// parseConfig unmarshals a buffer into a Config with default values. func parseConfig(conf []byte) (Config, error) { config := DefaultConfig if err := yaml.UnmarshalStrict(conf, &config); err != nil { @@ -303,7 +247,7 @@ func NewBucketWithConfig(logger log.Logger, config Config, component string) (*B rt = config.HTTPConfig.Transport } else { var err error - rt, err = DefaultTransport(config) + rt, err = exthttp.DefaultTransport(config.HTTPConfig) if err != nil { return nil, err } diff --git a/pkg/objstore/s3/s3_test.go b/pkg/objstore/s3/s3_test.go index f72ae89088..d9734ccf83 100644 --- a/pkg/objstore/s3/s3_test.go +++ b/pkg/objstore/s3/s3_test.go @@ -16,6 +16,7 @@ import ( "github.com/go-kit/log" "github.com/minio/minio-go/v7/pkg/encrypt" + "github.com/thanos-io/thanos/pkg/exthttp" "github.com/thanos-io/thanos/pkg/testutil" ) @@ -198,7 +199,7 @@ http_config: `) cfg, err := parseConfig(input) testutil.Ok(t, err) - transport, err := DefaultTransport(cfg) + transport, err := exthttp.DefaultTransport(cfg.HTTPConfig) testutil.Ok(t, err) testutil.Equals(t, true, transport.TLSClientConfig.InsecureSkipVerify) } diff --git a/test/e2e/e2ethanos/services.go b/test/e2e/e2ethanos/services.go index f64696a4c5..88868dc3b7 100644 --- a/test/e2e/e2ethanos/services.go +++ b/test/e2e/e2ethanos/services.go @@ -30,10 +30,11 @@ import ( "gopkg.in/yaml.v2" "github.com/thanos-io/thanos/pkg/alert" + "github.com/thanos-io/thanos/pkg/exthttp" "github.com/thanos-io/thanos/pkg/httpconfig" - "github.com/thanos-io/thanos/pkg/objstore" "github.com/thanos-io/thanos/pkg/objstore/client" "github.com/thanos-io/thanos/pkg/objstore/s3" + "github.com/thanos-io/thanos/pkg/queryfrontend" "github.com/thanos-io/thanos/pkg/receive" ) @@ -972,8 +973,8 @@ func NewS3Config(bucket, endpoint, basePath string) s3.Config { SecretKey: e2edb.MinioSecretKey, Endpoint: endpoint, Insecure: false, - HTTPConfig: s3.HTTPConfig{ - TLSConfig: objstore.TLSConfig{ + HTTPConfig: exthttp.HTTPConfig{ + TLSConfig: exthttp.TLSConfig{ CAFile: filepath.Join(basePath, "certs", "CAs", "ca.crt"), CertFile: filepath.Join(basePath, "certs", "public.crt"), KeyFile: filepath.Join(basePath, "certs", "private.key"),