diff --git a/src/chartserver/client.go b/src/chartserver/client.go index 030b7c246..f3307a488 100644 --- a/src/chartserver/client.go +++ b/src/chartserver/client.go @@ -10,8 +10,11 @@ import ( "sync" "time" + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" + commonhttp "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/lib/errors" + tracelib "github.com/goharbor/harbor/src/lib/trace" ) const ( @@ -22,7 +25,7 @@ const ( var ( once sync.Once - chartTransport *http.Transport + chartTransport http.RoundTripper ) // ChartClient is a http client to get the content from the external http server @@ -38,9 +41,13 @@ type ChartClient struct { // credential can be nil func NewChartClient(credential *Credential) *ChartClient { // Create http client with customized timeouts once.Do(func() { - chartTransport = commonhttp.GetHTTPTransport(commonhttp.SecureTransport).Clone() - chartTransport.MaxIdleConns = maxIdleConnections - chartTransport.IdleConnTimeout = idleConnectionTimeout + chartTransport = commonhttp.NewTransport( + commonhttp.WithMaxIdleConns(maxIdleConnections), + commonhttp.WithIdleconnectionTimeout(idleConnectionTimeout), + ) + if tracelib.Enabled() { + chartTransport = otelhttp.NewTransport(chartTransport) + } }) client := &http.Client{ diff --git a/src/chartserver/reverse_proxy.go b/src/chartserver/reverse_proxy.go index ebcd560b2..dce121975 100644 --- a/src/chartserver/reverse_proxy.go +++ b/src/chartserver/reverse_proxy.go @@ -53,7 +53,7 @@ func NewProxyEngine(target *url.URL, cred *Credential, middlewares ...func(http. director(target, cred, req) }, ModifyResponse: modifyResponse, - Transport: commonhttp.GetHTTPTransport(commonhttp.SecureTransport), + Transport: commonhttp.GetHTTPTransport(), } if len(middlewares) > 0 { diff --git a/src/cmd/exporter/main.go b/src/cmd/exporter/main.go index 8b284d294..4921d0e9a 100644 --- a/src/cmd/exporter/main.go +++ b/src/cmd/exporter/main.go @@ -1,11 +1,12 @@ package main import ( - "github.com/goharbor/harbor/src/common/models" "net/http" "os" "strings" + "github.com/goharbor/harbor/src/common/models" + _ "github.com/lib/pq" "github.com/prometheus/client_golang/prometheus" "github.com/spf13/viper" @@ -43,7 +44,7 @@ func main() { HarborHost: viper.GetString("service.host"), HarborPort: viper.GetInt("service.port"), Client: &http.Client{ - Transport: commonthttp.GetHTTPTransport(commonthttp.SecureTransport), + Transport: commonthttp.GetHTTPTransport(), }, }) diff --git a/src/common/http/client.go b/src/common/http/client.go index 43740c7b0..c2174b831 100644 --- a/src/common/http/client.go +++ b/src/common/http/client.go @@ -16,65 +16,18 @@ package http import ( "bytes" - "crypto/tls" "encoding/json" "errors" "io" "io/ioutil" - "net" "net/http" "net/url" "reflect" - "time" "github.com/goharbor/harbor/src/common/http/modifier" "github.com/goharbor/harbor/src/lib" ) -const ( - // InsecureTransport used to get the insecure http Transport - InsecureTransport = iota - // SecureTransport used to get the external secure http Transport - SecureTransport -) - -var ( - secureHTTPTransport *http.Transport - insecureHTTPTransport *http.Transport -) - -func init() { - secureHTTPTransport = newDefaultTransport() - insecureHTTPTransport = newDefaultTransport() - insecureHTTPTransport.TLSClientConfig.InsecureSkipVerify = true - - if InternalTLSEnabled() { - tlsConfig, err := GetInternalTLSConfig() - if err != nil { - panic(err) - } - secureHTTPTransport.TLSClientConfig = tlsConfig - } -} - -// Use this instead of Default Transport in library because it sets ForceAttemptHTTP2 to true -// And that options introduced in go 1.13 will cause the https requests hang forever in replication environment -func newDefaultTransport() *http.Transport { - return &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DialContext: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - DualStack: true, - }).DialContext, - TLSClientConfig: &tls.Config{}, - MaxIdleConns: 100, - IdleConnTimeout: 90 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, - ExpectContinueTimeout: 1 * time.Second, - } -} - // Client is a util for common HTTP operations, such Get, Head, Post, Put and Delete. // Use Do instead if those methods can not meet your requirement type Client struct { @@ -87,27 +40,6 @@ func (c *Client) GetClient() *http.Client { return c.client } -// GetHTTPTransport returns HttpTransport based on insecure configuration -func GetHTTPTransport(clientType uint) *http.Transport { - switch clientType { - case SecureTransport: - return secureHTTPTransport - case InsecureTransport: - return insecureHTTPTransport - default: - // default Transport is secure one - return secureHTTPTransport - } -} - -// GetHTTPTransportByInsecure returns a insecure HttpTransport if insecure is true or it returns secure one -func GetHTTPTransportByInsecure(insecure bool) *http.Transport { - if insecure { - return insecureHTTPTransport - } - return secureHTTPTransport -} - // NewClient creates an instance of Client. // Use net/http.Client as the default value if c is nil. // Modifiers modify the request before sending it. @@ -117,7 +49,7 @@ func NewClient(c *http.Client, modifiers ...modifier.Modifier) *Client { } if client.client == nil { client.client = &http.Client{ - Transport: GetHTTPTransport(SecureTransport), + Transport: GetHTTPTransport(), } } if len(modifiers) > 0 { diff --git a/src/common/http/client_test.go b/src/common/http/client_test.go deleted file mode 100644 index 176a0d81a..000000000 --- a/src/common/http/client_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package http - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestGetHTTPTransport(t *testing.T) { - transport := GetHTTPTransport(InsecureTransport) - assert.True(t, transport.TLSClientConfig.InsecureSkipVerify) - transport = GetHTTPTransport(SecureTransport) - assert.False(t, transport.TLSClientConfig.InsecureSkipVerify) -} diff --git a/src/common/http/transport.go b/src/common/http/transport.go new file mode 100644 index 000000000..6dd709d37 --- /dev/null +++ b/src/common/http/transport.go @@ -0,0 +1,126 @@ +// Copyright Project Harbor Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package http + +import ( + "crypto/tls" + "net" + "net/http" + "time" + + tracelib "github.com/goharbor/harbor/src/lib/trace" + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" +) + +const ( + // InsecureTransport used to get the insecure http Transport + InsecureTransport = iota + // SecureTransport used to get the external secure http Transport + SecureTransport +) + +var ( + secureHTTPTransport http.RoundTripper + insecureHTTPTransport http.RoundTripper +) + +func init() { + insecureHTTPTransport = NewTransport(WithInsecureSkipVerify(true)) + if InternalTLSEnabled() { + secureHTTPTransport = NewTransport(WithInternalTLSConfig()) + } else { + secureHTTPTransport = NewTransport() + } + if tracelib.Enabled() { + insecureHTTPTransport = otelhttp.NewTransport(insecureHTTPTransport) + secureHTTPTransport = otelhttp.NewTransport(secureHTTPTransport) + } +} + +// Use this instead of Default Transport in library because it sets ForceAttemptHTTP2 to true +// And that options introduced in go 1.13 will cause the https requests hang forever in replication environment +func newDefaultTransport() *http.Transport { + return &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + DualStack: true, + }).DialContext, + TLSClientConfig: &tls.Config{}, + MaxIdleConns: 100, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + } +} + +func WithInternalTLSConfig() func(*http.Transport) { + return func(tr *http.Transport) { + tlsConfig, err := GetInternalTLSConfig() + if err != nil { + panic(err) + } + tr.TLSClientConfig = tlsConfig + } +} +func WithInsecureSkipVerify(skipVerify bool) func(*http.Transport) { + return func(tr *http.Transport) { + tr.TLSClientConfig.InsecureSkipVerify = skipVerify + } +} + +func WithMaxIdleConns(maxIdleConns int) func(*http.Transport) { + return func(tr *http.Transport) { + tr.MaxIdleConns = maxIdleConns + } +} + +func WithIdleconnectionTimeout(idleConnectionTimeout time.Duration) func(*http.Transport) { + return func(tr *http.Transport) { + tr.IdleConnTimeout = idleConnectionTimeout + } +} + +func NewTransport(opts ...func(*http.Transport)) http.RoundTripper { + tr := newDefaultTransport() + for _, opt := range opts { + opt(tr) + } + return tr +} + +type TransportConfig struct { + Insecure bool +} +type TransportOption func(*TransportConfig) + +func WithInsecure(skipVerify bool) TransportOption { + return func(cfg *TransportConfig) { + cfg.Insecure = skipVerify + } +} + +// GetHTTPTransport returns HttpTransport based on insecure configuration +func GetHTTPTransport(opts ...TransportOption) http.RoundTripper { + cfg := &TransportConfig{} + for _, opt := range opts { + opt(cfg) + } + if cfg.Insecure { + return insecureHTTPTransport + } + return secureHTTPTransport +} diff --git a/src/common/http/transport_test.go b/src/common/http/transport_test.go new file mode 100644 index 000000000..1eb3f2aba --- /dev/null +++ b/src/common/http/transport_test.go @@ -0,0 +1,14 @@ +package http + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetHTTPTransport(t *testing.T) { + transport := GetHTTPTransport() + assert.Equal(t, secureHTTPTransport, transport, "Transport should be secure") + transport = GetHTTPTransport(WithInsecure(true)) + assert.Equal(t, insecureHTTPTransport, transport, "Transport should be insecure") +} diff --git a/src/common/job/client.go b/src/common/job/client.go index dcee622e3..0811e1980 100644 --- a/src/common/job/client.go +++ b/src/common/job/client.go @@ -5,12 +5,13 @@ import ( "encoding/json" "errors" "fmt" - "github.com/goharbor/harbor/src/lib/config" "io/ioutil" "net/http" "regexp" "strings" + "github.com/goharbor/harbor/src/lib/config" + commonhttp "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/common/http/modifier/auth" "github.com/goharbor/harbor/src/common/job/models" @@ -61,7 +62,7 @@ type DefaultClient struct { func NewDefaultClient(endpoint, secret string) *DefaultClient { var c *commonhttp.Client httpCli := &http.Client{ - Transport: commonhttp.GetHTTPTransport(commonhttp.SecureTransport), + Transport: commonhttp.GetHTTPTransport(), } if len(secret) > 0 { c = commonhttp.NewClient(httpCli, auth.NewSecretAuthorizer(secret)) @@ -81,12 +82,12 @@ func NewReplicationClient(endpoint, secret string) *DefaultClient { if len(secret) > 0 { c = commonhttp.NewClient(&http.Client{ - Transport: commonhttp.GetHTTPTransport(commonhttp.SecureTransport), + Transport: commonhttp.GetHTTPTransport(), }, auth.NewSecretAuthorizer(secret)) } else { c = commonhttp.NewClient(&http.Client{ - Transport: commonhttp.GetHTTPTransport(commonhttp.SecureTransport), + Transport: commonhttp.GetHTTPTransport(), }) } diff --git a/src/controller/health/checker.go b/src/controller/health/checker.go index 88e773d78..16ab2bc11 100644 --- a/src/controller/health/checker.go +++ b/src/controller/health/checker.go @@ -48,7 +48,7 @@ func HTTPStatusCodeHealthChecker(method string, url string, header http.Header, } client := httputil.NewClient(&http.Client{ - Transport: httputil.GetHTTPTransport(httputil.SecureTransport), + Transport: httputil.GetHTTPTransport(), Timeout: timeout, }) resp, err := client.Do(req) diff --git a/src/jobservice/job/impl/notification/http_helper.go b/src/jobservice/job/impl/notification/http_helper.go index ec519762f..856987b89 100644 --- a/src/jobservice/job/impl/notification/http_helper.go +++ b/src/jobservice/job/impl/notification/http_helper.go @@ -25,9 +25,9 @@ func init() { clients: map[string]*http.Client{}, } httpHelper.clients[secure] = &http.Client{ - Transport: commonhttp.GetHTTPTransport(commonhttp.SecureTransport), + Transport: commonhttp.GetHTTPTransport(), } httpHelper.clients[insecure] = &http.Client{ - Transport: commonhttp.GetHTTPTransport(commonhttp.InsecureTransport), + Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(true)), } } diff --git a/src/pkg/config/rest/rest.go b/src/pkg/config/rest/rest.go index a1fe81708..6c709c3e5 100644 --- a/src/pkg/config/rest/rest.go +++ b/src/pkg/config/rest/rest.go @@ -17,7 +17,6 @@ package rest import ( "context" "errors" - "net/http" commonhttp "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/common/http/modifier" @@ -32,11 +31,6 @@ type Driver struct { // NewRESTDriver - Create Driver func NewRESTDriver(configRESTURL string, modifiers ...modifier.Modifier) *Driver { - if commonhttp.InternalTLSEnabled() { - tr := commonhttp.GetHTTPTransport(commonhttp.SecureTransport) - return &Driver{configRESTURL: configRESTURL, client: commonhttp.NewClient(&http.Client{Transport: tr}, modifiers...)} - - } return &Driver{configRESTURL: configRESTURL, client: commonhttp.NewClient(nil, modifiers...)} } diff --git a/src/pkg/notification/policy/manager.go b/src/pkg/notification/policy/manager.go index 72fd6eaef..5dfdc28e5 100755 --- a/src/pkg/notification/policy/manager.go +++ b/src/pkg/notification/policy/manager.go @@ -3,6 +3,9 @@ package policy import ( "context" "fmt" + "net/http" + "time" + commonhttp "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/lib/errors" "github.com/goharbor/harbor/src/lib/log" @@ -10,8 +13,6 @@ import ( "github.com/goharbor/harbor/src/pkg/notification/policy/dao" "github.com/goharbor/harbor/src/pkg/notification/policy/model" notifier_model "github.com/goharbor/harbor/src/pkg/notifier/model" - "net/http" - "time" ) var ( @@ -159,7 +160,7 @@ func (m *manager) policyHTTPTest(address string, skipCertVerify bool) error { req.Header.Set("Content-Type", "application/json") client := http.Client{ - Transport: commonhttp.GetHTTPTransportByInsecure(skipCertVerify), + Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(skipCertVerify)), } resp, err := client.Do(req) diff --git a/src/pkg/reg/adapter/aliacr/adapter.go b/src/pkg/reg/adapter/aliacr/adapter.go index 0babad361..43f9b4efd 100644 --- a/src/pkg/reg/adapter/aliacr/adapter.go +++ b/src/pkg/reg/adapter/aliacr/adapter.go @@ -61,7 +61,7 @@ func newAdapter(registry *model.Registry) (*adapter, error) { return nil, err } credential := NewAuth(region, registry.Credential.AccessKey, registry.Credential.AccessSecret) - authorizer := bearer.NewAuthorizer(realm, service, credential, util.GetHTTPTransport(registry.Insecure)) + authorizer := bearer.NewAuthorizer(realm, service, credential, commonhttp.GetHTTPTransport(commonhttp.WithInsecure(registry.Insecure))) return &adapter{ region: region, registry: registry, @@ -71,11 +71,8 @@ func newAdapter(registry *model.Registry) (*adapter, error) { } func ping(registry *model.Registry) (string, string, error) { - client := &http.Client{} - if registry.Insecure { - client.Transport = commonhttp.GetHTTPTransport(commonhttp.InsecureTransport) - } else { - client.Transport = commonhttp.GetHTTPTransport(commonhttp.SecureTransport) + client := &http.Client{ + Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(registry.Insecure)), } resp, err := client.Get(registry.URL + "/v2/") diff --git a/src/pkg/reg/adapter/artifacthub/client.go b/src/pkg/reg/adapter/artifacthub/client.go index 79202b223..cc92207d1 100644 --- a/src/pkg/reg/adapter/artifacthub/client.go +++ b/src/pkg/reg/adapter/artifacthub/client.go @@ -3,11 +3,12 @@ package artifacthub import ( "encoding/json" "fmt" - "github.com/goharbor/harbor/src/lib/errors" - "github.com/goharbor/harbor/src/pkg/reg/model" - "github.com/goharbor/harbor/src/pkg/reg/util" "io/ioutil" "net/http" + + common_http "github.com/goharbor/harbor/src/common/http" + "github.com/goharbor/harbor/src/lib/errors" + "github.com/goharbor/harbor/src/pkg/reg/model" ) // Client is a client to interact with Artifact Hub @@ -19,7 +20,7 @@ type Client struct { func newClient(registry *model.Registry) *Client { return &Client{ httpClient: &http.Client{ - Transport: util.GetHTTPTransport(registry.Insecure), + Transport: common_http.GetHTTPTransport(common_http.WithInsecure(registry.Insecure)), }, } } diff --git a/src/pkg/reg/adapter/awsecr/auth.go b/src/pkg/reg/adapter/awsecr/auth.go index 8729e8f6f..62cb49984 100644 --- a/src/pkg/reg/adapter/awsecr/auth.go +++ b/src/pkg/reg/adapter/awsecr/auth.go @@ -18,19 +18,21 @@ import ( "encoding/base64" "errors" "fmt" + "net/http" + "net/url" + "strings" + "time" + + commonhttp "github.com/goharbor/harbor/src/common/http" + "github.com/goharbor/harbor/src/common/http/modifier" + "github.com/goharbor/harbor/src/lib/log" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds" "github.com/aws/aws-sdk-go/aws/session" awsecrapi "github.com/aws/aws-sdk-go/service/ecr" - commonhttp "github.com/goharbor/harbor/src/common/http" - "github.com/goharbor/harbor/src/common/http/modifier" - "github.com/goharbor/harbor/src/lib/log" - "net/http" - "net/url" - "strings" - "time" ) // Credential ... @@ -103,17 +105,12 @@ func getAwsSvc(region, accessKey, accessSecret string, insecure bool, forceEndpo } else { cred = ec2rolecreds.NewCredentials(sess) } - var tr *http.Transport - if insecure { - tr = commonhttp.GetHTTPTransport(commonhttp.InsecureTransport) - } else { - tr = commonhttp.GetHTTPTransport(commonhttp.SecureTransport) - } + config := &aws.Config{ Credentials: cred, Region: ®ion, HTTPClient: &http.Client{ - Transport: tr, + Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(insecure)), }, } if forceEndpoint != nil { diff --git a/src/pkg/reg/adapter/dockerhub/client.go b/src/pkg/reg/adapter/dockerhub/client.go index c86a47d2e..634f29308 100644 --- a/src/pkg/reg/adapter/dockerhub/client.go +++ b/src/pkg/reg/adapter/dockerhub/client.go @@ -8,9 +8,9 @@ import ( "io/ioutil" "net/http" + commonhttp "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/lib/log" "github.com/goharbor/harbor/src/pkg/reg/model" - "github.com/goharbor/harbor/src/pkg/reg/util" ) // Client is a client to interact with DockerHub @@ -26,7 +26,7 @@ func NewClient(registry *model.Registry) (*Client, error) { client := &Client{ host: registry.URL, client: &http.Client{ - Transport: util.GetHTTPTransport(registry.Insecure), + Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(registry.Insecure)), }, } diff --git a/src/pkg/reg/adapter/dtr/client.go b/src/pkg/reg/adapter/dtr/client.go index 60699e427..28a95d7b1 100644 --- a/src/pkg/reg/adapter/dtr/client.go +++ b/src/pkg/reg/adapter/dtr/client.go @@ -15,7 +15,6 @@ import ( "github.com/goharbor/harbor/src/lib/log" "github.com/goharbor/harbor/src/pkg/reg/model" - "github.com/goharbor/harbor/src/pkg/reg/util" ) // Client is a client to interact with DTR @@ -35,7 +34,7 @@ func NewClient(registry *model.Registry) *Client { password: registry.Credential.AccessSecret, client: common_http.NewClient( &http.Client{ - Transport: util.GetHTTPTransport(registry.Insecure), + Transport: common_http.GetHTTPTransport(common_http.WithInsecure(registry.Insecure)), }), } return client diff --git a/src/pkg/reg/adapter/dtr/client_test.go b/src/pkg/reg/adapter/dtr/client_test.go index 245d3a207..1618e0366 100644 --- a/src/pkg/reg/adapter/dtr/client_test.go +++ b/src/pkg/reg/adapter/dtr/client_test.go @@ -6,7 +6,6 @@ import ( common_http "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/common/utils/test" - "github.com/goharbor/harbor/src/pkg/reg/util" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -164,7 +163,7 @@ func TestProjects(t *testing.T) { username: "test", client: common_http.NewClient( &http.Client{ - Transport: util.GetHTTPTransport(true), + Transport: common_http.GetHTTPTransport(common_http.WithInsecure(true)), }), } diff --git a/src/pkg/reg/adapter/githubcr/adapter.go b/src/pkg/reg/adapter/githubcr/adapter.go index c10df63bd..5557abb9b 100644 --- a/src/pkg/reg/adapter/githubcr/adapter.go +++ b/src/pkg/reg/adapter/githubcr/adapter.go @@ -77,7 +77,7 @@ func newAdapter(registry *model.Registry) *adapter { registry.Credential.AccessSecret) } - var transport = util.GetHTTPTransport(registry.Insecure) + var transport = common_http.GetHTTPTransport(common_http.WithInsecure(registry.Insecure)) return &adapter{ Adapter: native.NewAdapter(registry), diff --git a/src/pkg/reg/adapter/gitlab/client.go b/src/pkg/reg/adapter/gitlab/client.go index d9ed53db9..8d79c0a9b 100644 --- a/src/pkg/reg/adapter/gitlab/client.go +++ b/src/pkg/reg/adapter/gitlab/client.go @@ -4,17 +4,16 @@ import ( "encoding/json" "errors" "fmt" - "github.com/docker/distribution/registry/client/auth/challenge" - "github.com/goharbor/harbor/src/lib/log" - "github.com/goharbor/harbor/src/pkg/reg/model" - "github.com/goharbor/harbor/src/pkg/reg/util" "io" "io/ioutil" "net/http" - - common_http "github.com/goharbor/harbor/src/common/http" "net/url" "reflect" + + "github.com/docker/distribution/registry/client/auth/challenge" + common_http "github.com/goharbor/harbor/src/common/http" + "github.com/goharbor/harbor/src/lib/log" + "github.com/goharbor/harbor/src/pkg/reg/model" ) const ( @@ -33,7 +32,7 @@ type Client struct { func NewClient(registry *model.Registry) (*Client, error) { realm, _, err := ping(&http.Client{ - Transport: util.GetHTTPTransport(registry.Insecure), + Transport: common_http.GetHTTPTransport(common_http.WithInsecure(registry.Insecure)), }, registry.URL) if err != nil { return nil, err @@ -51,7 +50,7 @@ func NewClient(registry *model.Registry) (*Client, error) { token: registry.Credential.AccessSecret, client: common_http.NewClient( &http.Client{ - Transport: util.GetHTTPTransport(registry.Insecure), + Transport: common_http.GetHTTPTransport(common_http.WithInsecure(registry.Insecure)), }), } return client, nil diff --git a/src/pkg/reg/adapter/gitlab/client_test.go b/src/pkg/reg/adapter/gitlab/client_test.go index 9bf4e83e9..627140881 100644 --- a/src/pkg/reg/adapter/gitlab/client_test.go +++ b/src/pkg/reg/adapter/gitlab/client_test.go @@ -1,13 +1,13 @@ package gitlab import ( - common_http "github.com/goharbor/harbor/src/common/http" - "github.com/goharbor/harbor/src/common/utils/test" - "github.com/goharbor/harbor/src/pkg/reg/util" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "net/http" "testing" + + common_http "github.com/goharbor/harbor/src/common/http" + "github.com/goharbor/harbor/src/common/utils/test" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestProjects(t *testing.T) { @@ -76,7 +76,7 @@ func TestProjects(t *testing.T) { token: "test", client: common_http.NewClient( &http.Client{ - Transport: util.GetHTTPTransport(true), + Transport: common_http.GetHTTPTransport(common_http.WithInsecure(true)), }), } projects, e := client.getProjects() diff --git a/src/pkg/reg/adapter/harbor/base/adapter.go b/src/pkg/reg/adapter/harbor/base/adapter.go index a6f3c0fee..408d7c8ee 100644 --- a/src/pkg/reg/adapter/harbor/base/adapter.go +++ b/src/pkg/reg/adapter/harbor/base/adapter.go @@ -40,7 +40,7 @@ func New(registry *model.Registry) (*Adapter, error) { // core, so insecure transport is ok // If using the secure one, as we'll replace the URL with 127.0.0.1 and this will // cause error "x509: cannot validate certificate for 127.0.0.1 because it doesn't contain any IP SANs" - Transport: common_http.GetHTTPTransport(common_http.InsecureTransport), + Transport: common_http.GetHTTPTransport(common_http.WithInsecure(true)), }, authorizer) client, err := NewClient(registry.URL, httpClient) if err != nil { @@ -62,7 +62,7 @@ func New(registry *model.Registry) (*Adapter, error) { registry.Credential.AccessSecret)) } httpClient := common_http.NewClient(&http.Client{ - Transport: common_http.GetHTTPTransportByInsecure(registry.Insecure), + Transport: common_http.GetHTTPTransport(common_http.WithInsecure(registry.Insecure)), }, authorizers...) client, err := NewClient(registry.URL, httpClient) if err != nil { diff --git a/src/pkg/reg/adapter/helmhub/client.go b/src/pkg/reg/adapter/helmhub/client.go index 72b0dfcc3..4f78e57ce 100644 --- a/src/pkg/reg/adapter/helmhub/client.go +++ b/src/pkg/reg/adapter/helmhub/client.go @@ -3,11 +3,12 @@ package helmhub import ( "encoding/json" "fmt" - "github.com/goharbor/harbor/src/lib/errors" - "github.com/goharbor/harbor/src/pkg/reg/model" - "github.com/goharbor/harbor/src/pkg/reg/util" "io/ioutil" "net/http" + + commonhttp "github.com/goharbor/harbor/src/common/http" + "github.com/goharbor/harbor/src/lib/errors" + "github.com/goharbor/harbor/src/pkg/reg/model" ) // ErrHTTPNotFound defines the return error when receiving 404 response code @@ -22,7 +23,7 @@ type Client struct { func NewClient(registry *model.Registry) *Client { return &Client{ client: &http.Client{ - Transport: util.GetHTTPTransport(registry.Insecure), + Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(registry.Insecure)), }, } } diff --git a/src/pkg/reg/adapter/huawei/huawei_adapter.go b/src/pkg/reg/adapter/huawei/huawei_adapter.go index 0311326c3..d7c8a4509 100644 --- a/src/pkg/reg/adapter/huawei/huawei_adapter.go +++ b/src/pkg/reg/adapter/huawei/huawei_adapter.go @@ -30,7 +30,6 @@ import ( adp "github.com/goharbor/harbor/src/pkg/reg/adapter" "github.com/goharbor/harbor/src/pkg/reg/adapter/native" "github.com/goharbor/harbor/src/pkg/reg/model" - "github.com/goharbor/harbor/src/pkg/reg/util" ) func init() { @@ -270,7 +269,7 @@ func newAdapter(registry *model.Registry) (adp.Adapter, error) { modifiers = append(modifiers, authorizer) } - transport := util.GetHTTPTransport(registry.Insecure) + transport := common_http.GetHTTPTransport(common_http.WithInsecure(registry.Insecure)) return &adapter{ Adapter: native.NewAdapter(registry), registry: registry, diff --git a/src/pkg/reg/adapter/jfrog/client.go b/src/pkg/reg/adapter/jfrog/client.go index 35e7d46fc..d7b35f91f 100644 --- a/src/pkg/reg/adapter/jfrog/client.go +++ b/src/pkg/reg/adapter/jfrog/client.go @@ -23,7 +23,6 @@ import ( common_http "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/pkg/reg/model" - "github.com/goharbor/harbor/src/pkg/reg/util" "github.com/goharbor/harbor/src/pkg/registry/auth/basic" ) @@ -48,7 +47,7 @@ func newClient(reg *model.Registry) *client { return &client{ client: common_http.NewClient( &http.Client{ - Transport: util.GetHTTPTransport(reg.Insecure), + Transport: common_http.GetHTTPTransport(common_http.WithInsecure(reg.Insecure)), }, basic.NewAuthorizer(username, password), ), diff --git a/src/pkg/reg/adapter/quay/adapter.go b/src/pkg/reg/adapter/quay/adapter.go index 12adcbf21..d25e30798 100644 --- a/src/pkg/reg/adapter/quay/adapter.go +++ b/src/pkg/reg/adapter/quay/adapter.go @@ -31,7 +31,6 @@ import ( "github.com/goharbor/harbor/src/pkg/reg/adapter/native" qauth "github.com/goharbor/harbor/src/pkg/reg/adapter/quay/auth" "github.com/goharbor/harbor/src/pkg/reg/model" - "github.com/goharbor/harbor/src/pkg/reg/util" ) var ( @@ -87,7 +86,7 @@ func newAdapter(registry *model.Registry) (*adapter, error) { registry: registry, client: common_http.NewClient( &http.Client{ - Transport: util.GetHTTPTransport(registry.Insecure), + Transport: common_http.GetHTTPTransport(common_http.WithInsecure(registry.Insecure)), }, modifiers..., ), diff --git a/src/pkg/reg/adapter/tencentcr/adapter.go b/src/pkg/reg/adapter/tencentcr/adapter.go index 32e4c83f3..ac47aff61 100644 --- a/src/pkg/reg/adapter/tencentcr/adapter.go +++ b/src/pkg/reg/adapter/tencentcr/adapter.go @@ -16,7 +16,6 @@ import ( adp "github.com/goharbor/harbor/src/pkg/reg/adapter" "github.com/goharbor/harbor/src/pkg/reg/adapter/native" "github.com/goharbor/harbor/src/pkg/reg/model" - "github.com/goharbor/harbor/src/pkg/reg/util" "github.com/goharbor/harbor/src/pkg/registry/auth/bearer" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" @@ -147,7 +146,7 @@ func newAdapter(registry *model.Registry) (a *adapter, err error) { } var credential = NewAuth(instanceInfo.RegistryId, client) - var transport = util.GetHTTPTransport(registry.Insecure) + var transport = commonhttp.GetHTTPTransport(commonhttp.WithInsecure(registry.Insecure)) var authorizer = bearer.NewAuthorizer(realm, service, credential, transport) return &adapter{ @@ -168,7 +167,7 @@ func newAdapter(registry *model.Registry) (a *adapter, err error) { func ping(registry *model.Registry) (string, string, error) { client := &http.Client{ - Transport: util.GetHTTPTransport(registry.Insecure), + Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(registry.Insecure)), } resp, err := client.Get(registry.URL + "/v2/") diff --git a/src/pkg/reg/util/util.go b/src/pkg/reg/util/util.go index acf97ca7f..6c007c1d2 100644 --- a/src/pkg/reg/util/util.go +++ b/src/pkg/reg/util/util.go @@ -15,20 +15,9 @@ package util import ( - "net/http" "strings" - - commonhttp "github.com/goharbor/harbor/src/common/http" ) -// GetHTTPTransport can be used to share the common HTTP transport -func GetHTTPTransport(insecure bool) *http.Transport { - if insecure { - return commonhttp.GetHTTPTransport(commonhttp.InsecureTransport) - } - return commonhttp.GetHTTPTransport(commonhttp.SecureTransport) -} - // ParseRepository parses the "repository" provided into two parts: namespace and the rest // the string before the last "/" is the namespace part // c -> [,c] diff --git a/src/pkg/reg/util/util_test.go b/src/pkg/reg/util/util_test.go index 04e79dca0..c0b34f8fb 100644 --- a/src/pkg/reg/util/util_test.go +++ b/src/pkg/reg/util/util_test.go @@ -20,13 +20,6 @@ import ( "github.com/stretchr/testify/assert" ) -func TestGetHTTPTransport(t *testing.T) { - transport := GetHTTPTransport(true) - assert.True(t, transport.TLSClientConfig.InsecureSkipVerify) - transport = GetHTTPTransport(false) - assert.False(t, transport.TLSClientConfig.InsecureSkipVerify) -} - func TestParseRepository(t *testing.T) { // empty repository repository := "" diff --git a/src/pkg/registry/auth/authorizer.go b/src/pkg/registry/auth/authorizer.go index 66310343d..39d4248b0 100644 --- a/src/pkg/registry/auth/authorizer.go +++ b/src/pkg/registry/auth/authorizer.go @@ -36,7 +36,7 @@ func NewAuthorizer(username, password string, insecure bool) lib.Authorizer { username: username, password: password, client: &http.Client{ - Transport: commonhttp.GetHTTPTransportByInsecure(insecure), + Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(insecure)), }, } } @@ -101,7 +101,7 @@ func (a *authorizer) initialize(u *url.URL) error { if challenge, exist := cm["bearer"]; exist { a.authorizer = bearer.NewAuthorizer(challenge.Parameters["realm"], challenge.Parameters["service"], basic.NewAuthorizer(a.username, a.password), - a.client.Transport.(*http.Transport)) + a.client.Transport) return nil } if _, exist := cm["basic"]; exist { diff --git a/src/pkg/registry/auth/bearer/authorizer.go b/src/pkg/registry/auth/bearer/authorizer.go index dd88f52e7..8de89188c 100644 --- a/src/pkg/registry/auth/bearer/authorizer.go +++ b/src/pkg/registry/auth/bearer/authorizer.go @@ -17,11 +17,12 @@ package bearer import ( "encoding/json" "fmt" - "github.com/goharbor/harbor/src/lib" - "github.com/goharbor/harbor/src/lib/errors" "io/ioutil" "net/http" "net/url" + + "github.com/goharbor/harbor/src/lib" + "github.com/goharbor/harbor/src/lib/errors" ) const ( @@ -30,18 +31,15 @@ const ( // NewAuthorizer return a bearer token authorizer // The parameter "a" is an authorizer used to fetch the token -func NewAuthorizer(realm, service string, a lib.Authorizer, transport ...*http.Transport) lib.Authorizer { +func NewAuthorizer(realm, service string, a lib.Authorizer, transport http.RoundTripper) lib.Authorizer { authorizer := &authorizer{ realm: realm, service: service, authorizer: a, cache: newCache(cacheCapacity), } - tp := http.DefaultTransport - if len(transport) > 0 && transport[0] != nil { - tp = transport[0] - } - authorizer.client = &http.Client{Transport: tp} + + authorizer.client = &http.Client{Transport: transport} return authorizer } diff --git a/src/pkg/registry/auth/bearer/authorizer_test.go b/src/pkg/registry/auth/bearer/authorizer_test.go index 85de90e86..134653032 100644 --- a/src/pkg/registry/auth/bearer/authorizer_test.go +++ b/src/pkg/registry/auth/bearer/authorizer_test.go @@ -16,13 +16,16 @@ package bearer import ( "fmt" - "github.com/goharbor/harbor/src/lib/errors" - "github.com/goharbor/harbor/src/pkg/registry/auth/basic" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "net/http" "net/http/httptest" "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + commonhttp "github.com/goharbor/harbor/src/common/http" + "github.com/goharbor/harbor/src/lib/errors" + "github.com/goharbor/harbor/src/pkg/registry/auth/basic" ) func TestModify(t *testing.T) { @@ -39,7 +42,7 @@ func TestModify(t *testing.T) { // invalid credential a := basic.NewAuthorizer("username", "invalid_password") - authorizer := NewAuthorizer(server.URL, "service", a) + authorizer := NewAuthorizer(server.URL, "service", a, commonhttp.NewTransport()) req, _ := http.NewRequest(http.MethodGet, server.URL, nil) err := authorizer.Modify(req) require.NotNil(t, err) @@ -47,7 +50,7 @@ func TestModify(t *testing.T) { // valid credential a = basic.NewAuthorizer("username", "password") - authorizer = NewAuthorizer(server.URL, "service", a) + authorizer = NewAuthorizer(server.URL, "service", a, commonhttp.NewTransport()) req, _ = http.NewRequest(http.MethodGet, server.URL, nil) err = authorizer.Modify(req) require.Nil(t, err) diff --git a/src/pkg/registry/client.go b/src/pkg/registry/client.go index 5acbab838..3c0d2f29b 100644 --- a/src/pkg/registry/client.go +++ b/src/pkg/registry/client.go @@ -18,7 +18,6 @@ import ( "bytes" "encoding/json" "fmt" - "github.com/goharbor/harbor/src/lib/config" "io" "io/ioutil" "net/http" @@ -27,6 +26,8 @@ import ( "strings" "time" + "github.com/goharbor/harbor/src/lib/config" + "github.com/docker/distribution" "github.com/docker/distribution/manifest/manifestlist" _ "github.com/docker/distribution/manifest/ocischema" // register oci manifest unmarshal function @@ -105,7 +106,7 @@ func NewClient(url, username, password string, insecure bool) Client { url: url, authorizer: auth.NewAuthorizer(username, password, insecure), client: &http.Client{ - Transport: commonhttp.GetHTTPTransportByInsecure(insecure), + Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(insecure)), Timeout: 30 * time.Minute, }, } @@ -113,18 +114,11 @@ func NewClient(url, username, password string, insecure bool) Client { // NewClientWithAuthorizer creates a registry client with the provided authorizer func NewClientWithAuthorizer(url string, authorizer lib.Authorizer, insecure bool) Client { - var transportType uint - if insecure { - transportType = commonhttp.InsecureTransport - } else { - transportType = commonhttp.SecureTransport - } - return &client{ url: url, authorizer: authorizer, client: &http.Client{ - Transport: commonhttp.GetHTTPTransport(transportType), + Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(insecure)), }, } } diff --git a/src/pkg/scan/job.go b/src/pkg/scan/job.go index 63978887b..b73fe055a 100644 --- a/src/pkg/scan/job.go +++ b/src/pkg/scan/job.go @@ -536,7 +536,7 @@ func makeBearerAuthorization(robotAccount *model.Robot, tokenURL string, reposit req.Header.Set("Authorization", auth) client := &http.Client{ - Transport: commonhttp.GetHTTPTransportByInsecure(true), + Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(true)), } resp, err := client.Do(req) diff --git a/src/pkg/signature/notary/helper.go b/src/pkg/signature/notary/helper.go index dfd8f3cf8..500972c05 100644 --- a/src/pkg/signature/notary/helper.go +++ b/src/pkg/signature/notary/helper.go @@ -18,23 +18,23 @@ import ( "context" "encoding/hex" "fmt" - "github.com/goharbor/harbor/src/lib/config" "net/http" "os" "path" "strings" - "github.com/docker/distribution/registry/auth/token" commonhttp "github.com/goharbor/harbor/src/common/http" tokenutil "github.com/goharbor/harbor/src/core/service/token" + "github.com/goharbor/harbor/src/lib/config" "github.com/goharbor/harbor/src/lib/log" model2 "github.com/goharbor/harbor/src/pkg/signature/notary/model" + + "github.com/docker/distribution/registry/auth/token" + digest "github.com/opencontainers/go-digest" "github.com/theupdateframework/notary" "github.com/theupdateframework/notary/client" "github.com/theupdateframework/notary/trustpinning" "github.com/theupdateframework/notary/tuf/data" - - digest "github.com/opencontainers/go-digest" ) var ( @@ -83,7 +83,7 @@ func GetTargets(ctx context.Context, notaryEndpoint string, username string, fqR authorizer := ¬aryAuthorizer{ token: t.Token, } - tr := NewTransport(commonhttp.GetHTTPTransport(commonhttp.SecureTransport), authorizer) + tr := NewTransport(commonhttp.GetHTTPTransport(), authorizer) gun := data.GUN(fqRepo) notaryRepo, err := client.NewFileCachedRepository(notaryCachePath, gun, notaryEndpoint, tr, mockRetriever, trustPin) if err != nil { diff --git a/src/registryctl/client/client.go b/src/registryctl/client/client.go index 555621b2c..7b0164aa6 100644 --- a/src/registryctl/client/client.go +++ b/src/registryctl/client/client.go @@ -16,7 +16,6 @@ package client import ( "fmt" - "github.com/goharbor/harbor/src/lib/errors" "io/ioutil" "net/http" "strings" @@ -62,9 +61,7 @@ func NewClient(baseURL string, cfg *Config) Client { } if cfg != nil { authorizer := auth.NewSecretAuthorizer(cfg.Secret) - client.client = common_http.NewClient(&http.Client{ - Transport: common_http.GetHTTPTransport(common_http.SecureTransport), - }, authorizer) + client.client = common_http.NewClient(nil, authorizer) } return client } diff --git a/src/server/registry/proxy.go b/src/server/registry/proxy.go index 4b59d8fc4..0ca6c367f 100644 --- a/src/server/registry/proxy.go +++ b/src/server/registry/proxy.go @@ -16,11 +16,12 @@ package registry import ( "fmt" - "github.com/goharbor/harbor/src/lib/config" "net/http" "net/http/httputil" "net/url" + "github.com/goharbor/harbor/src/lib/config" + commonhttp "github.com/goharbor/harbor/src/common/http" ) @@ -34,7 +35,7 @@ func newProxy() http.Handler { } proxy := httputil.NewSingleHostReverseProxy(url) if commonhttp.InternalTLSEnabled() { - proxy.Transport = commonhttp.GetHTTPTransport(commonhttp.SecureTransport) + proxy.Transport = commonhttp.GetHTTPTransport() } proxy.Director = basicAuthDirector(proxy.Director)