option: rename WithGetClientCertificate to WithClientCertSource

Change-Id: I90ab1f4420ee9535c3d462b19697e04975f88264
Reviewed-on: https://code-review.googlesource.com/c/google-api-go-client/+/52190
Reviewed-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Noah Dietz <ndietz@google.com>
Reviewed-by: Tyler Bui-Palsulich <tbp@google.com>
diff --git a/internal/settings.go b/internal/settings.go
index 64373f3..33ba7ac 100644
--- a/internal/settings.go
+++ b/internal/settings.go
@@ -18,24 +18,24 @@
 // DialSettings holds information needed to establish a connection with a
 // Google API service.
 type DialSettings struct {
-	Endpoint             string
-	DefaultEndpoint      string
-	Scopes               []string
-	TokenSource          oauth2.TokenSource
-	Credentials          *google.Credentials
-	CredentialsFile      string // if set, Token Source is ignored.
-	CredentialsJSON      []byte
-	UserAgent            string
-	APIKey               string
-	Audiences            []string
-	HTTPClient           *http.Client
-	GRPCDialOpts         []grpc.DialOption
-	GRPCConn             *grpc.ClientConn
-	GRPCConnPool         ConnPool
-	GRPCConnPoolSize     int
-	NoAuth               bool
-	TelemetryDisabled    bool
-	GetClientCertificate func(*tls.CertificateRequestInfo) (*tls.Certificate, error)
+	Endpoint          string
+	DefaultEndpoint   string
+	Scopes            []string
+	TokenSource       oauth2.TokenSource
+	Credentials       *google.Credentials
+	CredentialsFile   string // if set, Token Source is ignored.
+	CredentialsJSON   []byte
+	UserAgent         string
+	APIKey            string
+	Audiences         []string
+	HTTPClient        *http.Client
+	GRPCDialOpts      []grpc.DialOption
+	GRPCConn          *grpc.ClientConn
+	GRPCConnPool      ConnPool
+	GRPCConnPoolSize  int
+	NoAuth            bool
+	TelemetryDisabled bool
+	ClientCertSource  func(*tls.CertificateRequestInfo) (*tls.Certificate, error)
 
 	// Google API system parameters. For more information please read:
 	// https://cloud.google.com/apis/docs/system-parameters
@@ -93,11 +93,11 @@
 	if ds.HTTPClient != nil && ds.RequestReason != "" {
 		return errors.New("WithHTTPClient is incompatible with RequestReason")
 	}
-	if ds.HTTPClient != nil && ds.GetClientCertificate != nil {
-		return errors.New("WithHTTPClient is incompatible with WithGetClientCertificate")
+	if ds.HTTPClient != nil && ds.ClientCertSource != nil {
+		return errors.New("WithHTTPClient is incompatible with WithClientCertSource")
 	}
-	if ds.GetClientCertificate != nil && (ds.GRPCConn != nil || ds.GRPCConnPool != nil || ds.GRPCConnPoolSize != 0 || ds.GRPCDialOpts != nil) {
-		return errors.New("WithGetClientCertificate is currently only supported for HTTP. GRPC settings are incompatible")
+	if ds.ClientCertSource != nil && (ds.GRPCConn != nil || ds.GRPCConnPool != nil || ds.GRPCConnPoolSize != 0 || ds.GRPCDialOpts != nil) {
+		return errors.New("WithClientCertSource is currently only supported for HTTP. gRPC settings are incompatible")
 	}
 
 	return nil
diff --git a/internal/settings_test.go b/internal/settings_test.go
index 0ecf7cf..818e15b 100644
--- a/internal/settings_test.go
+++ b/internal/settings_test.go
@@ -34,7 +34,7 @@
 		// cloud clients add WithScopes to user-provided options to make
 		// the check feasible.
 		{NoAuth: true, Scopes: []string{"s"}},
-		{GetClientCertificate: dummyGetClientCertificate},
+		{ClientCertSource: dummyGetClientCertificate},
 	} {
 		err := ds.Validate()
 		if err != nil {
@@ -58,11 +58,11 @@
 		{Audiences: []string{"foo"}, Scopes: []string{"foo"}},
 		{HTTPClient: &http.Client{}, QuotaProject: "foo"},
 		{HTTPClient: &http.Client{}, RequestReason: "foo"},
-		{HTTPClient: &http.Client{}, GetClientCertificate: dummyGetClientCertificate},
-		{GetClientCertificate: dummyGetClientCertificate, GRPCConn: &grpc.ClientConn{}},
-		{GetClientCertificate: dummyGetClientCertificate, GRPCConnPool: struct{ ConnPool }{}},
-		{GetClientCertificate: dummyGetClientCertificate, GRPCDialOpts: []grpc.DialOption{grpc.WithInsecure()}},
-		{GetClientCertificate: dummyGetClientCertificate, GRPCConnPoolSize: 1},
+		{HTTPClient: &http.Client{}, ClientCertSource: dummyGetClientCertificate},
+		{ClientCertSource: dummyGetClientCertificate, GRPCConn: &grpc.ClientConn{}},
+		{ClientCertSource: dummyGetClientCertificate, GRPCConnPool: struct{ ConnPool }{}},
+		{ClientCertSource: dummyGetClientCertificate, GRPCDialOpts: []grpc.DialOption{grpc.WithInsecure()}},
+		{ClientCertSource: dummyGetClientCertificate, GRPCConnPoolSize: 1},
 	} {
 		err := ds.Validate()
 		if err == nil {
diff --git a/option/option.go b/option/option.go
index 4dbaea4..5fd1e4c 100644
--- a/option/option.go
+++ b/option/option.go
@@ -228,16 +228,24 @@
 // settings on gRPC and HTTP clients.
 // An example reason would be to bind custom telemetry that overrides the defaults.
 func WithTelemetryDisabled() ClientOption {
-	return withTelemetryDisabledOption{}
+	return withTelemetryDisabled{}
 }
 
-type withTelemetryDisabledOption struct{}
+type withTelemetryDisabled struct{}
 
-func (w withTelemetryDisabledOption) Apply(o *internal.DialSettings) {
+func (w withTelemetryDisabled) Apply(o *internal.DialSettings) {
 	o.TelemetryDisabled = true
 }
 
-// WithGetClientCertificate returns a ClientOption that specifies a
+// ClientCertSource is a function that returns a TLS client certificate to be used
+// when opening TLS connections.
+//
+// It follows the same semantics as crypto/tls.Config.GetClientCertificate.
+//
+// This is an EXPERIMENTAL API and may be changed or removed in the future.
+type ClientCertSource = func(*tls.CertificateRequestInfo) (*tls.Certificate, error)
+
+// WithClientCertSource returns a ClientOption that specifies a
 // callback function for obtaining a TLS client certificate.
 //
 // This option is used for supporting mTLS authentication, where the
@@ -251,14 +259,12 @@
 // should be returned.
 //
 // This is an EXPERIMENTAL API and may be changed or removed in the future.
-func WithGetClientCertificate(getClientCertificate func(*tls.CertificateRequestInfo) (*tls.Certificate, error)) ClientOption {
-	return withGetClientCertificate{getClientCertificate: getClientCertificate}
+func WithClientCertSource(s ClientCertSource) ClientOption {
+	return withClientCertSource{s}
 }
 
-type withGetClientCertificate struct {
-	getClientCertificate func(*tls.CertificateRequestInfo) (*tls.Certificate, error)
-}
+type withClientCertSource struct{ s ClientCertSource }
 
-func (w withGetClientCertificate) Apply(o *internal.DialSettings) {
-	o.GetClientCertificate = w.getClientCertificate
+func (w withClientCertSource) Apply(o *internal.DialSettings) {
+	o.ClientCertSource = w.s
 }
diff --git a/option/option_test.go b/option/option_test.go
index 9b0a6b0..089d586 100644
--- a/option/option_test.go
+++ b/option/option_test.go
@@ -97,29 +97,29 @@
 	}
 }
 
-func mockGetClientCertificate(info *tls.CertificateRequestInfo) (*tls.Certificate, error) {
+func mockClientCertSource(info *tls.CertificateRequestInfo) (*tls.Certificate, error) {
 	cert, _ := tls.X509KeyPair([]byte(certPEM), []byte(certPEM))
 	return &cert, nil
 }
 
-func TestApplyGetClientCertificate(t *testing.T) {
+func TestApplyClientCertSource(t *testing.T) {
 	opts := []ClientOption{
-		WithGetClientCertificate(mockGetClientCertificate),
+		WithClientCertSource(mockClientCertSource),
 	}
 	var got internal.DialSettings
 	for _, opt := range opts {
 		opt.Apply(&got)
 	}
 	want := internal.DialSettings{
-		GetClientCertificate: mockGetClientCertificate,
+		ClientCertSource: mockClientCertSource,
 	}
 
 	// Functions cannot be compared in Golang for equality, so we will compare the output of the functions instead.
-	certGot, err := got.GetClientCertificate(nil)
+	certGot, err := got.ClientCertSource(nil)
 	if err != nil {
 		t.Error(err)
 	}
-	certWant, err := want.GetClientCertificate(nil)
+	certWant, err := want.ClientCertSource(nil)
 	if err != nil {
 		t.Error(err)
 	}
diff --git a/transport/http/dial.go b/transport/http/dial.go
index cfea435..874a5cf 100644
--- a/transport/http/dial.go
+++ b/transport/http/dial.go
@@ -150,12 +150,18 @@
 func defaultBaseTransport(ctx context.Context, settings *internal.DialSettings) http.RoundTripper {
 	if appengineUrlfetchHook != nil {
 		return appengineUrlfetchHook(ctx)
-	} else if settings.GetClientCertificate != nil {
-		tlsConfig := tls.Config{GetClientCertificate: settings.GetClientCertificate}
-		return &http.Transport{TLSClientConfig: &tlsConfig}
-	} else {
-		return http.DefaultTransport
 	}
+
+	if settings.ClientCertSource != nil {
+		// TODO (cbro): copy default transport settings from http.DefaultTransport
+		return &http.Transport{
+			TLSClientConfig: &tls.Config{
+				GetClientCertificate: settings.ClientCertSource,
+			},
+		}
+	}
+
+	return http.DefaultTransport
 }
 
 func addOCTransport(trans http.RoundTripper, settings *internal.DialSettings) http.RoundTripper {