transport.go raw

   1  // Copyright 2023 Google LLC
   2  //
   3  // Licensed under the Apache License, Version 2.0 (the "License");
   4  // you may not use this file except in compliance with the License.
   5  // You may obtain a copy of the License at
   6  //
   7  //      http://www.apache.org/licenses/LICENSE-2.0
   8  //
   9  // Unless required by applicable law or agreed to in writing, software
  10  // distributed under the License is distributed on an "AS IS" BASIS,
  11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12  // See the License for the specific language governing permissions and
  13  // limitations under the License.
  14  
  15  // Package transport provided internal helpers for the two transport packages
  16  // (grpctransport and httptransport).
  17  package transport
  18  
  19  import (
  20  	"crypto/tls"
  21  	"fmt"
  22  	"net"
  23  	"net/http"
  24  	"time"
  25  
  26  	"cloud.google.com/go/auth/credentials"
  27  )
  28  
  29  // CloneDetectOptions clones a user set detect option into some new memory that
  30  // we can internally manipulate before sending onto the detect package.
  31  func CloneDetectOptions(oldDo *credentials.DetectOptions) *credentials.DetectOptions {
  32  	if oldDo == nil {
  33  		// it is valid for users not to set this, but we will need to to default
  34  		// some options for them in this case so return some initialized memory
  35  		// to work with.
  36  		return &credentials.DetectOptions{}
  37  	}
  38  	newDo := &credentials.DetectOptions{
  39  		// Simple types
  40  		TokenBindingType:  oldDo.TokenBindingType,
  41  		Audience:          oldDo.Audience,
  42  		Subject:           oldDo.Subject,
  43  		EarlyTokenRefresh: oldDo.EarlyTokenRefresh,
  44  		TokenURL:          oldDo.TokenURL,
  45  		STSAudience:       oldDo.STSAudience,
  46  		CredentialsFile:   oldDo.CredentialsFile,
  47  		UseSelfSignedJWT:  oldDo.UseSelfSignedJWT,
  48  		UniverseDomain:    oldDo.UniverseDomain,
  49  
  50  		// These fields are pointer types that we just want to use exactly as
  51  		// the user set, copy the ref
  52  		Client:             oldDo.Client,
  53  		Logger:             oldDo.Logger,
  54  		AuthHandlerOptions: oldDo.AuthHandlerOptions,
  55  	}
  56  
  57  	// Smartly size this memory and copy below.
  58  	if len(oldDo.CredentialsJSON) > 0 {
  59  		newDo.CredentialsJSON = make([]byte, len(oldDo.CredentialsJSON))
  60  		copy(newDo.CredentialsJSON, oldDo.CredentialsJSON)
  61  	}
  62  	if len(oldDo.Scopes) > 0 {
  63  		newDo.Scopes = make([]string, len(oldDo.Scopes))
  64  		copy(newDo.Scopes, oldDo.Scopes)
  65  	}
  66  
  67  	return newDo
  68  }
  69  
  70  // ValidateUniverseDomain verifies that the universe domain configured for the
  71  // client matches the universe domain configured for the credentials.
  72  func ValidateUniverseDomain(clientUniverseDomain, credentialsUniverseDomain string) error {
  73  	if clientUniverseDomain != credentialsUniverseDomain {
  74  		return fmt.Errorf(
  75  			"the configured universe domain (%q) does not match the universe "+
  76  				"domain found in the credentials (%q). If you haven't configured "+
  77  				"the universe domain explicitly, \"googleapis.com\" is the default",
  78  			clientUniverseDomain,
  79  			credentialsUniverseDomain)
  80  	}
  81  	return nil
  82  }
  83  
  84  // DefaultHTTPClientWithTLS constructs an HTTPClient using the provided tlsConfig, to support mTLS.
  85  func DefaultHTTPClientWithTLS(tlsConfig *tls.Config) *http.Client {
  86  	trans := BaseTransport()
  87  	trans.TLSClientConfig = tlsConfig
  88  	return &http.Client{Transport: trans}
  89  }
  90  
  91  // BaseTransport returns a default [http.Transport] which can be used if
  92  // [http.DefaultTransport] has been overwritten.
  93  func BaseTransport() *http.Transport {
  94  	return &http.Transport{
  95  		Proxy: http.ProxyFromEnvironment,
  96  		DialContext: (&net.Dialer{
  97  			Timeout:   30 * time.Second,
  98  			KeepAlive: 30 * time.Second,
  99  			DualStack: true,
 100  		}).DialContext,
 101  		MaxIdleConns:          100,
 102  		MaxIdleConnsPerHost:   100,
 103  		IdleConnTimeout:       90 * time.Second,
 104  		TLSHandshakeTimeout:   10 * time.Second,
 105  		ExpectContinueTimeout: 1 * time.Second,
 106  	}
 107  }
 108