From c2cf7b32f65b9c51082a9ce88c2765b52c61c0ee Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon <grzegorz@gitlab.com> Date: Fri, 23 Sep 2022 10:19:59 +0000 Subject: [PATCH] Add user-agent to all http requests initiated by Workhorse --- workhorse/internal/api/api.go | 1 - .../dependencyproxy/dependencyproxy.go | 4 +- .../helper/httptransport/http_transport.go | 37 ------------ .../internal/imageresizer/image_resizer.go | 4 +- workhorse/internal/sendurl/sendurl.go | 4 +- workhorse/internal/transport/transport.go | 58 +++++++++++++++++++ .../upload/destination/objectstore/object.go | 4 +- workhorse/internal/version/version.go | 20 +++++++ workhorse/internal/version/version_test.go | 19 ++++++ .../internal/zipartifacts/open_archive.go | 6 +- workhorse/main.go | 5 +- 11 files changed, 112 insertions(+), 50 deletions(-) delete mode 100644 workhorse/internal/helper/httptransport/http_transport.go create mode 100644 workhorse/internal/transport/transport.go create mode 100644 workhorse/internal/version/version.go create mode 100644 workhorse/internal/version/version_test.go diff --git a/workhorse/internal/api/api.go b/workhorse/internal/api/api.go index aa6d7cf1bc785..6a6a51b27bbd0 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 90f3042a342c4..6651b5aee8417 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 c7c3c5283f5d0..0000000000000 --- 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 8c3271b6f11ba..092369cd2af8b 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/sendurl/sendurl.go b/workhorse/internal/sendurl/sendurl.go index 205ec8a0e9fbb..8e679c6b47524 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 0000000000000..f19d332a28a63 --- /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 36ffa0eb12e72..1086332312c0f 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/version/version.go b/workhorse/internal/version/version.go new file mode 100644 index 0000000000000..790edf8ffca9b --- /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 0000000000000..9d0581e093b3d --- /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 881ef915d75da..d477725a39f72 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 ), } diff --git a/workhorse/main.go b/workhorse/main.go index b0f9760b0d5db..ca9b86de528a7 100644 --- a/workhorse/main.go +++ b/workhorse/main.go @@ -23,6 +23,7 @@ import ( "gitlab.com/gitlab-org/gitlab/workhorse/internal/redis" "gitlab.com/gitlab-org/gitlab/workhorse/internal/secret" "gitlab.com/gitlab-org/gitlab/workhorse/internal/upstream" + "gitlab.com/gitlab-org/gitlab/workhorse/internal/version" ) // Version is the current version of GitLab Workhorse @@ -55,8 +56,10 @@ func main() { os.Exit(2) } + version.SetVersion(Version, BuildTime) + if boot.printVersion { - fmt.Printf("gitlab-workhorse %s-%s\n", Version, BuildTime) + fmt.Println(version.GetApplicationVersion()) os.Exit(0) } -- GitLab