Skip to content

Commit

Permalink
refactor: use sync.Once to initialize auth http clients (#159)
Browse files Browse the repository at this point in the history
This commit modifies the Container, CP4D, and IAM
authenticators so that they are all consistent with the
VPC authenticator in the way in which they obtain an
HTTP client instance for invoking operations.
  • Loading branch information
padamstx authored Mar 31, 2022
1 parent 8bc69b2 commit ffdd490
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 57 deletions.
41 changes: 23 additions & 18 deletions v5/core/container_authenticator.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ type ContainerAuthenticator struct {

// [optional] The http.Client object used in interacts with the IAM token server.
// If not specified by the user, a suitable default Client will be constructed.
Client *http.Client
Client *http.Client
clientInit sync.Once

// The cached IAM access token and its expiration time.
tokenData *iamTokenData
Expand Down Expand Up @@ -177,6 +178,26 @@ func (builder *ContainerAuthenticatorBuilder) Build() (*ContainerAuthenticator,
return &builder.ContainerAuthenticator, nil
}

// client returns the authenticator's http client after potentially initializing it.
func (authenticator *ContainerAuthenticator) client() *http.Client {
authenticator.clientInit.Do(func() {
if authenticator.Client == nil {
authenticator.Client = DefaultHTTPClient()
authenticator.Client.Timeout = time.Second * 30

// If the user told us to disable SSL verification, then do it now.
if authenticator.DisableSSLVerification {
transport := &http.Transport{
// #nosec G402
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
authenticator.Client.Transport = transport
}
}
})
return authenticator.Client
}

// newContainerAuthenticatorFromMap constructs a new ContainerAuthenticator instance from a map containing
// configuration properties.
func newContainerAuthenticatorFromMap(properties map[string]string) (authenticator *ContainerAuthenticator, err error) {
Expand Down Expand Up @@ -400,22 +421,6 @@ func (authenticator *ContainerAuthenticator) RequestToken() (*IamTokenServerResp
req.SetBasicAuth(authenticator.ClientID, authenticator.ClientSecret)
}

// If the authenticator does not have a Client, create one now.
if authenticator.Client == nil {
authenticator.Client = &http.Client{
Timeout: time.Second * 30,
}

// If the user told us to disable SSL verification, then do it now.
if authenticator.DisableSSLVerification {
transport := &http.Transport{
// #nosec G402
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
authenticator.Client.Transport = transport
}
}

// If debug is enabled, then dump the request.
if GetLogger().IsLogLevelEnabled(LevelDebug) {
buf, dumpErr := httputil.DumpRequestOut(req, req.Body != nil)
Expand All @@ -427,7 +432,7 @@ func (authenticator *ContainerAuthenticator) RequestToken() (*IamTokenServerResp
}

GetLogger().Debug("Invoking IAM 'get token' operation: %s", builder.URL)
resp, err := authenticator.Client.Do(req)
resp, err := authenticator.client().Do(req)
if err != nil {
return nil, NewAuthenticationError(&DetailedResponse{}, err)
}
Expand Down
41 changes: 23 additions & 18 deletions v5/core/cp4d_authenticator.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ type CloudPakForDataAuthenticator struct {

// The http.Client object used to invoke token server requests [optional]. If
// not specified, a suitable default Client will be constructed.
Client *http.Client
Client *http.Client
clientInit sync.Once

// The cached token and expiration time.
tokenData *cp4dTokenData
Expand Down Expand Up @@ -157,6 +158,26 @@ func (authenticator *CloudPakForDataAuthenticator) Validate() error {
return nil
}

// client returns the authenticator's http client after potentially initializing it.
func (authenticator *CloudPakForDataAuthenticator) client() *http.Client {
authenticator.clientInit.Do(func() {
if authenticator.Client == nil {
authenticator.Client = DefaultHTTPClient()
authenticator.Client.Timeout = time.Second * 30

// If the user told us to disable SSL verification, then do it now.
if authenticator.DisableSSLVerification {
transport := &http.Transport{
// #nosec G402
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
authenticator.Client.Transport = transport
}
}
})
return authenticator.Client
}

// Authenticate adds the bearer token (obtained from the token server) to the
// specified request.
//
Expand Down Expand Up @@ -294,22 +315,6 @@ func (authenticator *CloudPakForDataAuthenticator) requestToken() (tokenResponse
return
}

// If the authenticator does not have a Client, create one now.
if authenticator.Client == nil {
authenticator.Client = &http.Client{
Timeout: time.Second * 30,
}

// If the user told us to disable SSL verification, then do it now.
if authenticator.DisableSSLVerification {
transport := &http.Transport{
// #nosec G402
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
authenticator.Client.Transport = transport
}
}

// If debug is enabled, then dump the request.
if GetLogger().IsLogLevelEnabled(LevelDebug) {
buf, dumpErr := httputil.DumpRequestOut(req, req.Body != nil)
Expand All @@ -321,7 +326,7 @@ func (authenticator *CloudPakForDataAuthenticator) requestToken() (tokenResponse
}

GetLogger().Debug("Invoking CP4D token service operation: %s", builder.URL)
resp, err := authenticator.Client.Do(req)
resp, err := authenticator.client().Do(req)
if err != nil {
return
}
Expand Down
41 changes: 23 additions & 18 deletions v5/core/iam_authenticator.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ type IamAuthenticator struct {

// [Optional] The http.Client object used to invoke token server requests.
// If not specified by the user, a suitable default Client will be constructed.
Client *http.Client
Client *http.Client
clientInit sync.Once

// The cached token and expiration time.
tokenData *iamTokenData
Expand Down Expand Up @@ -167,6 +168,26 @@ func (builder *IamAuthenticatorBuilder) Build() (*IamAuthenticator, error) {
return &builder.IamAuthenticator, nil
}

// client returns the authenticator's http client after potentially initializing it.
func (authenticator *IamAuthenticator) client() *http.Client {
authenticator.clientInit.Do(func() {
if authenticator.Client == nil {
authenticator.Client = DefaultHTTPClient()
authenticator.Client.Timeout = time.Second * 30

// If the user told us to disable SSL verification, then do it now.
if authenticator.DisableSSLVerification {
transport := &http.Transport{
// #nosec G402
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
authenticator.Client.Transport = transport
}
}
})
return authenticator.Client
}

// NewIamAuthenticator constructs a new IamAuthenticator instance.
// Deprecated - use the IamAuthenticatorBuilder instead.
func NewIamAuthenticator(apiKey string, url string, clientId string, clientSecret string,
Expand Down Expand Up @@ -423,22 +444,6 @@ func (authenticator *IamAuthenticator) RequestToken() (*IamTokenServerResponse,
req.SetBasicAuth(authenticator.ClientId, authenticator.ClientSecret)
}

// If the authenticator does not have a Client, create one now.
if authenticator.Client == nil {
authenticator.Client = &http.Client{
Timeout: time.Second * 30,
}

// If the user told us to disable SSL verification, then do it now.
if authenticator.DisableSSLVerification {
transport := &http.Transport{
// #nosec G402
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
authenticator.Client.Transport = transport
}
}

// If debug is enabled, then dump the request.
if GetLogger().IsLogLevelEnabled(LevelDebug) {
buf, dumpErr := httputil.DumpRequestOut(req, req.Body != nil)
Expand All @@ -450,7 +455,7 @@ func (authenticator *IamAuthenticator) RequestToken() (*IamTokenServerResponse,
}

GetLogger().Debug("Invoking IAM 'get token' operation: %s", builder.URL)
resp, err := authenticator.Client.Do(req)
resp, err := authenticator.client().Do(req)
if err != nil {
return nil, err
}
Expand Down
5 changes: 2 additions & 3 deletions v5/core/vpc_instance_authenticator.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,8 @@ func (builder *VpcInstanceAuthenticatorBuilder) Build() (*VpcInstanceAuthenticat
func (authenticator *VpcInstanceAuthenticator) client() *http.Client {
authenticator.clientInit.Do(func() {
if authenticator.Client == nil {
authenticator.Client = &http.Client{
Timeout: vpcauthDefaultTimeout,
}
authenticator.Client = DefaultHTTPClient()
authenticator.Client.Timeout = vpcauthDefaultTimeout
}
})
return authenticator.Client
Expand Down

0 comments on commit ffdd490

Please sign in to comment.