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