diff options
Diffstat (limited to 'workhorse/internal')
18 files changed, 155 insertions, 96 deletions
diff --git a/workhorse/internal/api/api.go b/workhorse/internal/api/api.go index aa6d7cf1bc7..6a6a51b27bb 100644 --- a/workhorse/internal/api/api.go +++ b/workhorse/internal/api/api.go @@ -19,7 +19,6 @@ import ( "gitlab.com/gitlab-org/gitlab/workhorse/internal/config" "gitlab.com/gitlab-org/gitlab/workhorse/internal/helper" "gitlab.com/gitlab-org/gitlab/workhorse/internal/log" - "gitlab.com/gitlab-org/gitlab/workhorse/internal/secret" ) diff --git a/workhorse/internal/dependencyproxy/dependencyproxy.go b/workhorse/internal/dependencyproxy/dependencyproxy.go index 90f3042a342..6651b5aee84 100644 --- a/workhorse/internal/dependencyproxy/dependencyproxy.go +++ b/workhorse/internal/dependencyproxy/dependencyproxy.go @@ -9,12 +9,12 @@ import ( "gitlab.com/gitlab-org/labkit/log" "gitlab.com/gitlab-org/gitlab/workhorse/internal/helper" - "gitlab.com/gitlab-org/gitlab/workhorse/internal/helper/httptransport" "gitlab.com/gitlab-org/gitlab/workhorse/internal/senddata" + "gitlab.com/gitlab-org/gitlab/workhorse/internal/transport" ) var httpClient = &http.Client{ - Transport: httptransport.New(), + Transport: transport.NewRestrictedTransport(), } type Injector struct { diff --git a/workhorse/internal/helper/httptransport/http_transport.go b/workhorse/internal/helper/httptransport/http_transport.go deleted file mode 100644 index c7c3c5283f5..00000000000 --- a/workhorse/internal/helper/httptransport/http_transport.go +++ /dev/null @@ -1,37 +0,0 @@ -package httptransport - -import ( - "net/http" - "time" - - "gitlab.com/gitlab-org/labkit/correlation" - "gitlab.com/gitlab-org/labkit/tracing" -) - -type Option func(*http.Transport) - -// Defines a http.Transport with values -// that are more restrictive than for http.DefaultTransport, -// they define shorter TLS Handshake, and more aggressive connection closing -// to prevent the connection hanging and reduce FD usage -func New(options ...Option) http.RoundTripper { - t := http.DefaultTransport.(*http.Transport).Clone() - - // To avoid keep around TCP connections to http servers we're done with - t.MaxIdleConns = 2 - - // A stricter timeout for fetching from external sources that can be slow - t.ResponseHeaderTimeout = 30 * time.Second - - for _, option := range options { - option(t) - } - - return tracing.NewRoundTripper(correlation.NewInstrumentedRoundTripper(t)) -} - -func WithDisabledCompression() Option { - return func(t *http.Transport) { - t.DisableCompression = true - } -} diff --git a/workhorse/internal/imageresizer/image_resizer.go b/workhorse/internal/imageresizer/image_resizer.go index 8c3271b6f11..092369cd2af 100644 --- a/workhorse/internal/imageresizer/image_resizer.go +++ b/workhorse/internal/imageresizer/image_resizer.go @@ -21,9 +21,9 @@ import ( "gitlab.com/gitlab-org/gitlab/workhorse/internal/config" "gitlab.com/gitlab-org/gitlab/workhorse/internal/helper" - "gitlab.com/gitlab-org/gitlab/workhorse/internal/helper/httptransport" "gitlab.com/gitlab-org/gitlab/workhorse/internal/log" "gitlab.com/gitlab-org/gitlab/workhorse/internal/senddata" + "gitlab.com/gitlab-org/gitlab/workhorse/internal/transport" ) type Resizer struct { @@ -69,7 +69,7 @@ const ( var envInjector = tracing.NewEnvInjector() var httpClient = &http.Client{ - Transport: httptransport.New(), + Transport: transport.NewRestrictedTransport(), } const ( diff --git a/workhorse/internal/queueing/queue.go b/workhorse/internal/queueing/queue.go index db082cf19c6..c8d32280355 100644 --- a/workhorse/internal/queueing/queue.go +++ b/workhorse/internal/queueing/queue.go @@ -26,11 +26,10 @@ type queueMetrics struct { // newQueueMetrics prepares Prometheus metrics for queueing mechanism // name specifies name of the queue, used to label metrics with ConstLabel `queue_name` -// Don't call newQueueMetrics twice with the same name argument! // timeout specifies the timeout of storing a request in queue - queueMetrics // uses it to calculate histogram buckets for gitlab_workhorse_queueing_waiting_time // metric -func newQueueMetrics(name string, timeout time.Duration) *queueMetrics { +func newQueueMetrics(name string, timeout time.Duration, reg prometheus.Registerer) *queueMetrics { waitingTimeBuckets := []float64{ timeout.Seconds() * 0.01, timeout.Seconds() * 0.05, @@ -44,8 +43,9 @@ func newQueueMetrics(name string, timeout time.Duration) *queueMetrics { timeout.Seconds(), } + promFactory := promauto.With(reg) metrics := &queueMetrics{ - queueingLimit: promauto.NewGauge(prometheus.GaugeOpts{ + queueingLimit: promFactory.NewGauge(prometheus.GaugeOpts{ Name: "gitlab_workhorse_queueing_limit", Help: "Current limit set for the queueing mechanism", ConstLabels: prometheus.Labels{ @@ -53,7 +53,7 @@ func newQueueMetrics(name string, timeout time.Duration) *queueMetrics { }, }), - queueingQueueLimit: promauto.NewGauge(prometheus.GaugeOpts{ + queueingQueueLimit: promFactory.NewGauge(prometheus.GaugeOpts{ Name: "gitlab_workhorse_queueing_queue_limit", Help: "Current queueLimit set for the queueing mechanism", ConstLabels: prometheus.Labels{ @@ -61,7 +61,7 @@ func newQueueMetrics(name string, timeout time.Duration) *queueMetrics { }, }), - queueingQueueTimeout: promauto.NewGauge(prometheus.GaugeOpts{ + queueingQueueTimeout: promFactory.NewGauge(prometheus.GaugeOpts{ Name: "gitlab_workhorse_queueing_queue_timeout", Help: "Current queueTimeout set for the queueing mechanism", ConstLabels: prometheus.Labels{ @@ -69,7 +69,7 @@ func newQueueMetrics(name string, timeout time.Duration) *queueMetrics { }, }), - queueingBusy: promauto.NewGauge(prometheus.GaugeOpts{ + queueingBusy: promFactory.NewGauge(prometheus.GaugeOpts{ Name: "gitlab_workhorse_queueing_busy", Help: "How many queued requests are now processed", ConstLabels: prometheus.Labels{ @@ -77,7 +77,7 @@ func newQueueMetrics(name string, timeout time.Duration) *queueMetrics { }, }), - queueingWaiting: promauto.NewGauge(prometheus.GaugeOpts{ + queueingWaiting: promFactory.NewGauge(prometheus.GaugeOpts{ Name: "gitlab_workhorse_queueing_waiting", Help: "How many requests are now queued", ConstLabels: prometheus.Labels{ @@ -85,7 +85,7 @@ func newQueueMetrics(name string, timeout time.Duration) *queueMetrics { }, }), - queueingWaitingTime: promauto.NewHistogram(prometheus.HistogramOpts{ + queueingWaitingTime: promFactory.NewHistogram(prometheus.HistogramOpts{ Name: "gitlab_workhorse_queueing_waiting_time", Help: "How many time a request spent in queue", ConstLabels: prometheus.Labels{ @@ -94,7 +94,7 @@ func newQueueMetrics(name string, timeout time.Duration) *queueMetrics { Buckets: waitingTimeBuckets, }), - queueingErrors: promauto.NewCounterVec( + queueingErrors: promFactory.NewCounterVec( prometheus.CounterOpts{ Name: "gitlab_workhorse_queueing_errors", Help: "How many times the TooManyRequests or QueueintTimedout errors were returned while queueing, partitioned by error type", @@ -120,12 +120,11 @@ type Queue struct { // newQueue creates a new queue // name specifies name used to label queue metrics. -// Don't call newQueue twice with the same name argument! // limit specifies number of requests run concurrently // queueLimit specifies maximum number of requests that can be queued // timeout specifies the time limit of storing the request in the queue // if the number of requests is above the limit -func newQueue(name string, limit, queueLimit uint, timeout time.Duration) *Queue { +func newQueue(name string, limit, queueLimit uint, timeout time.Duration, reg prometheus.Registerer) *Queue { queue := &Queue{ name: name, busyCh: make(chan struct{}, limit), @@ -133,7 +132,7 @@ func newQueue(name string, limit, queueLimit uint, timeout time.Duration) *Queue timeout: timeout, } - queue.queueMetrics = newQueueMetrics(name, timeout) + queue.queueMetrics = newQueueMetrics(name, timeout, reg) queue.queueingLimit.Set(float64(limit)) queue.queueingQueueLimit.Set(float64(queueLimit)) queue.queueingQueueTimeout.Set(timeout.Seconds()) diff --git a/workhorse/internal/queueing/queue_test.go b/workhorse/internal/queueing/queue_test.go index 7f5ed9154f4..dee0df76c67 100644 --- a/workhorse/internal/queueing/queue_test.go +++ b/workhorse/internal/queueing/queue_test.go @@ -3,10 +3,12 @@ package queueing import ( "testing" "time" + + "github.com/prometheus/client_golang/prometheus" ) func TestNormalQueueing(t *testing.T) { - q := newQueue("queue 1", 2, 1, time.Microsecond) + q := newQueue("queue name", 2, 1, time.Microsecond, prometheus.NewRegistry()) err1 := q.Acquire() if err1 != nil { t.Fatal("we should acquire a new slot") @@ -31,7 +33,7 @@ func TestNormalQueueing(t *testing.T) { } func TestQueueLimit(t *testing.T) { - q := newQueue("queue 2", 1, 0, time.Microsecond) + q := newQueue("queue name", 1, 0, time.Microsecond, prometheus.NewRegistry()) err1 := q.Acquire() if err1 != nil { t.Fatal("we should acquire a new slot") @@ -44,7 +46,7 @@ func TestQueueLimit(t *testing.T) { } func TestQueueProcessing(t *testing.T) { - q := newQueue("queue 3", 1, 1, time.Second) + q := newQueue("queue name", 1, 1, time.Second, prometheus.NewRegistry()) err1 := q.Acquire() if err1 != nil { t.Fatal("we should acquire a new slot") diff --git a/workhorse/internal/queueing/requests.go b/workhorse/internal/queueing/requests.go index 3a22cb367ce..34d4c985f53 100644 --- a/workhorse/internal/queueing/requests.go +++ b/workhorse/internal/queueing/requests.go @@ -4,6 +4,8 @@ import ( "net/http" "time" + "github.com/prometheus/client_golang/prometheus" + "gitlab.com/gitlab-org/gitlab/workhorse/internal/helper" ) @@ -19,7 +21,7 @@ const ( // limit specifies number of requests run concurrently // queueLimit specifies maximum number of requests that can be queued // queueTimeout specifies the time limit of storing the request in the queue -func QueueRequests(name string, h http.Handler, limit, queueLimit uint, queueTimeout time.Duration) http.Handler { +func QueueRequests(name string, h http.Handler, limit, queueLimit uint, queueTimeout time.Duration, reg prometheus.Registerer) http.Handler { if limit == 0 { return h } @@ -27,7 +29,7 @@ func QueueRequests(name string, h http.Handler, limit, queueLimit uint, queueTim queueTimeout = DefaultTimeout } - queue := newQueue(name, limit, queueLimit, queueTimeout) + queue := newQueue(name, limit, queueLimit, queueTimeout, reg) return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { err := queue.Acquire() diff --git a/workhorse/internal/queueing/requests_test.go b/workhorse/internal/queueing/requests_test.go index f1c52e5c6f5..eb098a6242e 100644 --- a/workhorse/internal/queueing/requests_test.go +++ b/workhorse/internal/queueing/requests_test.go @@ -6,6 +6,8 @@ import ( "net/http/httptest" "testing" "time" + + "github.com/prometheus/client_golang/prometheus" ) var httpHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -21,7 +23,7 @@ func pausedHttpHandler(pauseCh chan struct{}) http.Handler { func TestNormalRequestProcessing(t *testing.T) { w := httptest.NewRecorder() - h := QueueRequests("Normal request processing", httpHandler, 1, 1, time.Second) + h := QueueRequests("Normal request processing", httpHandler, 1, 1, time.Second, prometheus.NewRegistry()) h.ServeHTTP(w, nil) if w.Code != 200 { t.Fatal("QueueRequests should process request") @@ -36,7 +38,7 @@ func testSlowRequestProcessing(name string, count int, limit, queueLimit uint, q pauseCh := make(chan struct{}) defer close(pauseCh) - handler := QueueRequests("Slow request processing: "+name, pausedHttpHandler(pauseCh), limit, queueLimit, queueTimeout) + handler := QueueRequests("Slow request processing: "+name, pausedHttpHandler(pauseCh), limit, queueLimit, queueTimeout, prometheus.NewRegistry()) respCh := make(chan *httptest.ResponseRecorder, count) diff --git a/workhorse/internal/redis/redis.go b/workhorse/internal/redis/redis.go index 588fba6e242..03118cfcef6 100644 --- a/workhorse/internal/redis/redis.go +++ b/workhorse/internal/redis/redis.go @@ -1,7 +1,6 @@ package redis import ( - "errors" "fmt" "net" "net/url" @@ -164,7 +163,15 @@ func sentinelDialer(dopts []redis.DialOption) redisDialerFunc { return nil, err } dopts = append(dopts, redis.DialNetDial(keepAliveDialer)) - return redisDial("tcp", address, dopts...) + conn, err := redisDial("tcp", address, dopts...) + if err != nil { + return nil, err + } + if !sentinel.TestRole(conn, "master") { + conn.Close() + return nil, fmt.Errorf("%s is not redis master", address) + } + return conn, nil } } @@ -247,14 +254,6 @@ func Configure(cfg *config.RedisConfig, dialFunc func(*config.RedisConfig, bool) Dial: poolDialFunc, Wait: true, } - if sntnl != nil { - pool.TestOnBorrow = func(c redis.Conn, t time.Time) error { - if !sentinel.TestRole(c, "master") { - return errors.New("role check failed") - } - return nil - } - } } // Get a connection for the Redis-pool diff --git a/workhorse/internal/sendurl/sendurl.go b/workhorse/internal/sendurl/sendurl.go index 205ec8a0e9f..8e679c6b475 100644 --- a/workhorse/internal/sendurl/sendurl.go +++ b/workhorse/internal/sendurl/sendurl.go @@ -11,9 +11,9 @@ import ( "gitlab.com/gitlab-org/labkit/mask" "gitlab.com/gitlab-org/gitlab/workhorse/internal/helper" - "gitlab.com/gitlab-org/gitlab/workhorse/internal/helper/httptransport" "gitlab.com/gitlab-org/gitlab/workhorse/internal/log" "gitlab.com/gitlab-org/gitlab/workhorse/internal/senddata" + "gitlab.com/gitlab-org/gitlab/workhorse/internal/transport" ) type entry struct{ senddata.Prefix } @@ -44,7 +44,7 @@ var preserveHeaderKeys = map[string]bool{ "Pragma": true, // Support for HTTP 1.0 proxies } -var httpTransport = httptransport.New() +var httpTransport = transport.NewRestrictedTransport() var httpClient = &http.Client{ Transport: httpTransport, diff --git a/workhorse/internal/transport/transport.go b/workhorse/internal/transport/transport.go new file mode 100644 index 00000000000..f19d332a28a --- /dev/null +++ b/workhorse/internal/transport/transport.go @@ -0,0 +1,58 @@ +package transport + +import ( + "net/http" + "time" + + "gitlab.com/gitlab-org/labkit/correlation" + "gitlab.com/gitlab-org/labkit/tracing" + + "gitlab.com/gitlab-org/gitlab/workhorse/internal/version" +) + +// Creates a new default transport that has Workhorse's User-Agent header set. +func NewDefaultTransport() http.RoundTripper { + return &DefaultTransport{Next: http.DefaultTransport} +} + +// Defines a http.Transport with values that are more restrictive than for +// http.DefaultTransport, they define shorter TLS Handshake, and more +// aggressive connection closing to prevent the connection hanging and reduce +// FD usage +func NewRestrictedTransport(options ...Option) http.RoundTripper { + return &DefaultTransport{Next: newRestrictedTransport(options...)} +} + +type DefaultTransport struct { + Next http.RoundTripper +} + +func (t DefaultTransport) RoundTrip(req *http.Request) (*http.Response, error) { + req.Header.Set("User-Agent", version.GetUserAgent()) + + return t.Next.RoundTrip(req) +} + +type Option func(*http.Transport) + +func WithDisabledCompression() Option { + return func(t *http.Transport) { + t.DisableCompression = true + } +} + +func newRestrictedTransport(options ...Option) http.RoundTripper { + t := http.DefaultTransport.(*http.Transport).Clone() + + // To avoid keep around TCP connections to http servers we're done with + t.MaxIdleConns = 2 + + // A stricter timeout for fetching from external sources that can be slow + t.ResponseHeaderTimeout = 30 * time.Second + + for _, option := range options { + option(t) + } + + return tracing.NewRoundTripper(correlation.NewInstrumentedRoundTripper(t)) +} diff --git a/workhorse/internal/upload/destination/objectstore/object.go b/workhorse/internal/upload/destination/objectstore/object.go index 36ffa0eb12e..1086332312c 100644 --- a/workhorse/internal/upload/destination/objectstore/object.go +++ b/workhorse/internal/upload/destination/objectstore/object.go @@ -8,11 +8,11 @@ import ( "gitlab.com/gitlab-org/labkit/mask" - "gitlab.com/gitlab-org/gitlab/workhorse/internal/helper/httptransport" + "gitlab.com/gitlab-org/gitlab/workhorse/internal/transport" ) var httpClient = &http.Client{ - Transport: httptransport.New(), + Transport: transport.NewRestrictedTransport(), } // Object represents an object on a S3 compatible Object Store service. diff --git a/workhorse/internal/upload/destination/objectstore/s3_session.go b/workhorse/internal/upload/destination/objectstore/s3_session.go index d71b38eb22e..e1fe6fbbdc9 100644 --- a/workhorse/internal/upload/destination/objectstore/s3_session.go +++ b/workhorse/internal/upload/destination/objectstore/s3_session.go @@ -37,17 +37,13 @@ func (s *s3Session) isExpired() bool { return time.Now().After(s.expiry) } -func newS3SessionCache() *s3SessionCache { - return &s3SessionCache{sessions: make(map[config.S3Config]*s3Session)} -} - var ( // By default, it looks like IAM instance profiles may last 6 hours // (via curl http://169.254.169.254/latest/meta-data/iam/security-credentials/<role_name>), // but this may be configurable from anywhere for 15 minutes to 12 // hours. To be safe, refresh AWS sessions every 10 minutes. sessionExpiration = time.Duration(10 * time.Minute) - sessionCache = newS3SessionCache() + sessionCache = &s3SessionCache{sessions: make(map[config.S3Config]*s3Session)} ) // SetupS3Session initializes a new AWS S3 session and refreshes one if @@ -105,10 +101,3 @@ func setupS3Session(s3Credentials config.S3Credentials, s3Config config.S3Config return sess, nil } - -func ResetS3Session(s3Config config.S3Config) { - sessionCache.Lock() - defer sessionCache.Unlock() - - delete(sessionCache.sessions, s3Config) -} diff --git a/workhorse/internal/upload/destination/objectstore/s3_session_test.go b/workhorse/internal/upload/destination/objectstore/s3_session_test.go index 4bbe38f90ec..b7bbee0ef69 100644 --- a/workhorse/internal/upload/destination/objectstore/s3_session_test.go +++ b/workhorse/internal/upload/destination/objectstore/s3_session_test.go @@ -12,6 +12,8 @@ import ( ) func TestS3SessionSetup(t *testing.T) { + resetS3Sessions() + credentials := config.S3Credentials{} cfg := config.S3Config{Region: "us-west-1", PathStyle: true} @@ -28,11 +30,11 @@ func TestS3SessionSetup(t *testing.T) { _, err = setupS3Session(credentials, anotherConfig) require.NoError(t, err) require.Equal(t, len(sessionCache.sessions), 1) - - ResetS3Session(cfg) } func TestS3SessionEndpointSetup(t *testing.T) { + resetS3Sessions() + credentials := config.S3Credentials{} const customS3Endpoint = "https://example.com" const region = "us-west-2" @@ -48,11 +50,11 @@ func TestS3SessionEndpointSetup(t *testing.T) { stsConfig := sess.ClientConfig(endpoints.StsServiceID) require.Equal(t, "https://sts.amazonaws.com", stsConfig.Endpoint, "STS should use default endpoint") - - ResetS3Session(cfg) } func TestS3SessionExpiry(t *testing.T) { + resetS3Sessions() + credentials := config.S3Credentials{} cfg := config.S3Config{Region: "us-west-1", PathStyle: true} @@ -75,6 +77,10 @@ func TestS3SessionExpiry(t *testing.T) { nextSession, ok := sessionCache.sessions[cfg] require.True(t, ok) require.False(t, nextSession.isExpired()) +} - ResetS3Session(cfg) +func resetS3Sessions() { + sessionCache.Lock() + defer sessionCache.Unlock() + sessionCache.sessions = make(map[config.S3Config]*s3Session) } diff --git a/workhorse/internal/upstream/routes.go b/workhorse/internal/upstream/routes.go index 40cd012a890..08e3ef8c9f1 100644 --- a/workhorse/internal/upstream/routes.go +++ b/workhorse/internal/upstream/routes.go @@ -6,6 +6,7 @@ import ( "regexp" "github.com/gorilla/websocket" + "github.com/prometheus/client_golang/prometheus" "gitlab.com/gitlab-org/labkit/log" "gitlab.com/gitlab-org/labkit/tracing" @@ -221,7 +222,7 @@ func configureRoutes(u *upstream) { mimeMultipartUploader := upload.Multipart(api, signingProxy, preparer) tempfileMultipartProxy := upload.FixedPreAuthMultipart(api, proxy, preparer) - ciAPIProxyQueue := queueing.QueueRequests("ci_api_job_requests", tempfileMultipartProxy, u.APILimit, u.APIQueueLimit, u.APIQueueTimeout) + ciAPIProxyQueue := queueing.QueueRequests("ci_api_job_requests", tempfileMultipartProxy, u.APILimit, u.APIQueueLimit, u.APIQueueTimeout, prometheus.DefaultRegisterer) ciAPILongPolling := builds.RegisterHandler(ciAPIProxyQueue, u.watchKeyHandler, u.APICILongPollingDuration) dependencyProxyInjector.SetUploadHandler(requestBodyUploader) diff --git a/workhorse/internal/version/version.go b/workhorse/internal/version/version.go new file mode 100644 index 00000000000..790edf8ffca --- /dev/null +++ b/workhorse/internal/version/version.go @@ -0,0 +1,20 @@ +package version + +import "fmt" + +var version = "unknown" +var build = "unknown" +var schema = "gitlab-workhorse (%s)-(%s)" + +func SetVersion(v, b string) { + version = v + build = b +} + +func GetUserAgent() string { + return GetApplicationVersion() +} + +func GetApplicationVersion() string { + return fmt.Sprintf(schema, version, build) +} diff --git a/workhorse/internal/version/version_test.go b/workhorse/internal/version/version_test.go new file mode 100644 index 00000000000..9d0581e093b --- /dev/null +++ b/workhorse/internal/version/version_test.go @@ -0,0 +1,19 @@ +package version + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestVersion(t *testing.T) { + require.Equal(t, GetApplicationVersion(), "gitlab-workhorse (unknown)-(unknown)") + + SetVersion("15.3", "123.123") + + require.Equal(t, GetApplicationVersion(), "gitlab-workhorse (15.3)-(123.123)") + + SetVersion("", "123.123") + + require.Equal(t, GetApplicationVersion(), "gitlab-workhorse ()-(123.123)") +} diff --git a/workhorse/internal/zipartifacts/open_archive.go b/workhorse/internal/zipartifacts/open_archive.go index 881ef915d75..d477725a39f 100644 --- a/workhorse/internal/zipartifacts/open_archive.go +++ b/workhorse/internal/zipartifacts/open_archive.go @@ -8,16 +8,16 @@ import ( "os" "strings" - "gitlab.com/gitlab-org/gitlab/workhorse/internal/helper/httptransport" "gitlab.com/gitlab-org/gitlab/workhorse/internal/httprs" + "gitlab.com/gitlab-org/gitlab/workhorse/internal/transport" zip "gitlab.com/gitlab-org/golang-archive-zip" "gitlab.com/gitlab-org/labkit/mask" ) var httpClient = &http.Client{ - Transport: httptransport.New( - httptransport.WithDisabledCompression(), // To avoid bugs when serving compressed files from object storage + Transport: transport.NewRestrictedTransport( + transport.WithDisabledCompression(), // To avoid bugs when serving compressed files from object storage ), } |