chore: migrate to gitea
This commit is contained in:
254
vendor/cloud.google.com/go/auth/httptransport/httptransport.go
generated
vendored
Normal file
254
vendor/cloud.google.com/go/auth/httptransport/httptransport.go
generated
vendored
Normal file
@@ -0,0 +1,254 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// 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 httptransport provides functionality for managing HTTP client
|
||||
// connections to Google Cloud services.
|
||||
package httptransport
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
|
||||
"cloud.google.com/go/auth"
|
||||
detect "cloud.google.com/go/auth/credentials"
|
||||
"cloud.google.com/go/auth/internal/transport"
|
||||
"cloud.google.com/go/auth/internal/transport/headers"
|
||||
"github.com/googleapis/gax-go/v2/internallog"
|
||||
)
|
||||
|
||||
// ClientCertProvider 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].
|
||||
type ClientCertProvider = func(*tls.CertificateRequestInfo) (*tls.Certificate, error)
|
||||
|
||||
// Options used to configure a [net/http.Client] from [NewClient].
|
||||
type Options struct {
|
||||
// DisableTelemetry disables default telemetry (OpenTelemetry). An example
|
||||
// reason to do so would be to bind custom telemetry that overrides the
|
||||
// defaults.
|
||||
DisableTelemetry bool
|
||||
// DisableAuthentication specifies that no authentication should be used. It
|
||||
// is suitable only for testing and for accessing public resources, like
|
||||
// public Google Cloud Storage buckets.
|
||||
DisableAuthentication bool
|
||||
// Headers are extra HTTP headers that will be appended to every outgoing
|
||||
// request.
|
||||
Headers http.Header
|
||||
// BaseRoundTripper overrides the base transport used for serving requests.
|
||||
// If specified ClientCertProvider is ignored.
|
||||
BaseRoundTripper http.RoundTripper
|
||||
// Endpoint overrides the default endpoint to be used for a service.
|
||||
Endpoint string
|
||||
// APIKey specifies an API key to be used as the basis for authentication.
|
||||
// If set DetectOpts are ignored.
|
||||
APIKey string
|
||||
// Credentials used to add Authorization header to all requests. If set
|
||||
// DetectOpts are ignored.
|
||||
Credentials *auth.Credentials
|
||||
// ClientCertProvider 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.
|
||||
ClientCertProvider ClientCertProvider
|
||||
// DetectOpts configures settings for detect Application Default
|
||||
// Credentials.
|
||||
DetectOpts *detect.DetectOptions
|
||||
// UniverseDomain is the default service domain for a given Cloud universe.
|
||||
// The default value is "googleapis.com". This is the universe domain
|
||||
// configured for the client, which will be compared to the universe domain
|
||||
// that is separately configured for the credentials.
|
||||
UniverseDomain string
|
||||
// Logger is used for debug logging. If provided, logging will be enabled
|
||||
// at the loggers configured level. By default logging is disabled unless
|
||||
// enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default
|
||||
// logger will be used. Optional.
|
||||
Logger *slog.Logger
|
||||
|
||||
// InternalOptions are NOT meant to be set directly by consumers of this
|
||||
// package, they should only be set by generated client code.
|
||||
InternalOptions *InternalOptions
|
||||
}
|
||||
|
||||
func (o *Options) validate() error {
|
||||
if o == nil {
|
||||
return errors.New("httptransport: opts required to be non-nil")
|
||||
}
|
||||
if o.InternalOptions != nil && o.InternalOptions.SkipValidation {
|
||||
return nil
|
||||
}
|
||||
hasCreds := o.APIKey != "" ||
|
||||
o.Credentials != nil ||
|
||||
(o.DetectOpts != nil && len(o.DetectOpts.CredentialsJSON) > 0) ||
|
||||
(o.DetectOpts != nil && o.DetectOpts.CredentialsFile != "")
|
||||
if o.DisableAuthentication && hasCreds {
|
||||
return errors.New("httptransport: DisableAuthentication is incompatible with options that set or detect credentials")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// client returns the client a user set for the detect options or nil if one was
|
||||
// not set.
|
||||
func (o *Options) client() *http.Client {
|
||||
if o.DetectOpts != nil && o.DetectOpts.Client != nil {
|
||||
return o.DetectOpts.Client
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Options) logger() *slog.Logger {
|
||||
return internallog.New(o.Logger)
|
||||
}
|
||||
|
||||
func (o *Options) resolveDetectOptions() *detect.DetectOptions {
|
||||
io := o.InternalOptions
|
||||
// soft-clone these so we are not updating a ref the user holds and may reuse
|
||||
do := transport.CloneDetectOptions(o.DetectOpts)
|
||||
|
||||
// If scoped JWTs are enabled user provided an aud, allow self-signed JWT.
|
||||
if (io != nil && io.EnableJWTWithScope) || do.Audience != "" {
|
||||
do.UseSelfSignedJWT = true
|
||||
}
|
||||
// Only default scopes if user did not also set an audience.
|
||||
if len(do.Scopes) == 0 && do.Audience == "" && io != nil && len(io.DefaultScopes) > 0 {
|
||||
do.Scopes = make([]string, len(io.DefaultScopes))
|
||||
copy(do.Scopes, io.DefaultScopes)
|
||||
}
|
||||
if len(do.Scopes) == 0 && do.Audience == "" && io != nil {
|
||||
do.Audience = o.InternalOptions.DefaultAudience
|
||||
}
|
||||
if o.ClientCertProvider != nil {
|
||||
tlsConfig := &tls.Config{
|
||||
GetClientCertificate: o.ClientCertProvider,
|
||||
}
|
||||
do.Client = transport.DefaultHTTPClientWithTLS(tlsConfig)
|
||||
do.TokenURL = detect.GoogleMTLSTokenURL
|
||||
}
|
||||
if do.Logger == nil {
|
||||
do.Logger = o.logger()
|
||||
}
|
||||
return do
|
||||
}
|
||||
|
||||
// InternalOptions are only meant to be set by generated client code. These are
|
||||
// not meant to be set directly by consumers of this package. Configuration in
|
||||
// this type is considered EXPERIMENTAL and may be removed at any time in the
|
||||
// future without warning.
|
||||
type InternalOptions struct {
|
||||
// EnableJWTWithScope specifies if scope can be used with self-signed JWT.
|
||||
EnableJWTWithScope bool
|
||||
// DefaultAudience specifies a default audience to be used as the audience
|
||||
// field ("aud") for the JWT token authentication.
|
||||
DefaultAudience string
|
||||
// DefaultEndpointTemplate combined with UniverseDomain specifies the
|
||||
// default endpoint.
|
||||
DefaultEndpointTemplate string
|
||||
// DefaultMTLSEndpoint specifies the default mTLS endpoint.
|
||||
DefaultMTLSEndpoint string
|
||||
// DefaultScopes specifies the default OAuth2 scopes to be used for a
|
||||
// service.
|
||||
DefaultScopes []string
|
||||
// SkipValidation bypasses validation on Options. It should only be used
|
||||
// internally for clients that need more control over their transport.
|
||||
SkipValidation bool
|
||||
// SkipUniverseDomainValidation skips the verification that the universe
|
||||
// domain configured for the client matches the universe domain configured
|
||||
// for the credentials. It should only be used internally for clients that
|
||||
// need more control over their transport. The default is false.
|
||||
SkipUniverseDomainValidation bool
|
||||
// TelemetryAttributes specifies a map of telemetry attributes to be added
|
||||
// to all OpenTelemetry signals, such as tracing and metrics, for purposes
|
||||
// including representing the static identity of the client (e.g., service
|
||||
// name, version). These attributes are expected to be consistent across all
|
||||
// signals to enable cross-signal correlation.
|
||||
//
|
||||
// It should only be used internally by generated clients. Callers should not
|
||||
// modify the map after it is passed in.
|
||||
TelemetryAttributes map[string]string
|
||||
}
|
||||
|
||||
// AddAuthorizationMiddleware adds a middleware to the provided client's
|
||||
// transport that sets the Authorization header with the value produced by the
|
||||
// provided [cloud.google.com/go/auth.Credentials]. An error is returned only
|
||||
// if client or creds is nil.
|
||||
//
|
||||
// This function does not support setting a universe domain value on the client.
|
||||
func AddAuthorizationMiddleware(client *http.Client, creds *auth.Credentials) error {
|
||||
if client == nil || creds == nil {
|
||||
return fmt.Errorf("httptransport: client and tp must not be nil")
|
||||
}
|
||||
base := client.Transport
|
||||
if base == nil {
|
||||
if dt, ok := http.DefaultTransport.(*http.Transport); ok {
|
||||
base = dt.Clone()
|
||||
} else {
|
||||
// Directly reuse the DefaultTransport if the application has
|
||||
// replaced it with an implementation of RoundTripper other than
|
||||
// http.Transport.
|
||||
base = http.DefaultTransport
|
||||
}
|
||||
}
|
||||
client.Transport = &authTransport{
|
||||
creds: creds,
|
||||
base: base,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewClient returns a [net/http.Client] that can be used to communicate with a
|
||||
// Google cloud service, configured with the provided [Options]. It
|
||||
// automatically appends Authorization headers to all outgoing requests.
|
||||
func NewClient(opts *Options) (*http.Client, error) {
|
||||
if err := opts.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tOpts := &transport.Options{
|
||||
Endpoint: opts.Endpoint,
|
||||
ClientCertProvider: opts.ClientCertProvider,
|
||||
Client: opts.client(),
|
||||
UniverseDomain: opts.UniverseDomain,
|
||||
Logger: opts.logger(),
|
||||
}
|
||||
if io := opts.InternalOptions; io != nil {
|
||||
tOpts.DefaultEndpointTemplate = io.DefaultEndpointTemplate
|
||||
tOpts.DefaultMTLSEndpoint = io.DefaultMTLSEndpoint
|
||||
}
|
||||
clientCertProvider, dialTLSContext, err := transport.GetHTTPTransportConfig(tOpts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
baseRoundTripper := opts.BaseRoundTripper
|
||||
if baseRoundTripper == nil {
|
||||
baseRoundTripper = defaultBaseTransport(clientCertProvider, dialTLSContext)
|
||||
}
|
||||
// Ensure the token exchange transport uses the same ClientCertProvider as the API transport.
|
||||
opts.ClientCertProvider = clientCertProvider
|
||||
trans, err := newTransport(baseRoundTripper, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &http.Client{
|
||||
Transport: trans,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SetAuthHeader uses the provided token to set the Authorization and trust
|
||||
// boundary headers on an http.Request. If the token.Type is empty, the type is
|
||||
// assumed to be Bearer. This is the recommended way to set authorization
|
||||
// headers on a custom http.Request.
|
||||
func SetAuthHeader(token *auth.Token, req *http.Request) {
|
||||
headers.SetAuthHeader(token, req)
|
||||
}
|
||||
235
vendor/cloud.google.com/go/auth/httptransport/transport.go
generated
vendored
Normal file
235
vendor/cloud.google.com/go/auth/httptransport/transport.go
generated
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// 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 httptransport
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/auth"
|
||||
"cloud.google.com/go/auth/credentials"
|
||||
"cloud.google.com/go/auth/internal"
|
||||
"cloud.google.com/go/auth/internal/transport"
|
||||
"cloud.google.com/go/auth/internal/transport/cert"
|
||||
"cloud.google.com/go/auth/internal/transport/headers"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
"golang.org/x/net/http2"
|
||||
)
|
||||
|
||||
const (
|
||||
quotaProjectHeaderKey = "X-goog-user-project"
|
||||
)
|
||||
|
||||
func newTransport(base http.RoundTripper, opts *Options) (http.RoundTripper, error) {
|
||||
var headers = opts.Headers
|
||||
ht := &headerTransport{
|
||||
base: base,
|
||||
headers: headers,
|
||||
}
|
||||
var trans http.RoundTripper = ht
|
||||
trans = addOpenTelemetryTransport(trans, opts)
|
||||
switch {
|
||||
case opts.DisableAuthentication:
|
||||
// Do nothing.
|
||||
case opts.APIKey != "":
|
||||
qp := internal.GetQuotaProject(nil, opts.Headers.Get(quotaProjectHeaderKey))
|
||||
if qp != "" {
|
||||
if headers == nil {
|
||||
headers = make(map[string][]string, 1)
|
||||
}
|
||||
headers.Set(quotaProjectHeaderKey, qp)
|
||||
}
|
||||
trans = &apiKeyTransport{
|
||||
Transport: trans,
|
||||
Key: opts.APIKey,
|
||||
}
|
||||
default:
|
||||
var creds *auth.Credentials
|
||||
if opts.Credentials != nil {
|
||||
creds = opts.Credentials
|
||||
} else {
|
||||
var err error
|
||||
creds, err = credentials.DetectDefault(opts.resolveDetectOptions())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
qp, err := creds.QuotaProjectID(context.Background())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if qp != "" {
|
||||
if headers == nil {
|
||||
headers = make(map[string][]string, 1)
|
||||
}
|
||||
// Don't overwrite user specified quota
|
||||
if v := headers.Get(quotaProjectHeaderKey); v == "" {
|
||||
headers.Set(quotaProjectHeaderKey, qp)
|
||||
}
|
||||
}
|
||||
var skipUD bool
|
||||
if iOpts := opts.InternalOptions; iOpts != nil {
|
||||
skipUD = iOpts.SkipUniverseDomainValidation
|
||||
}
|
||||
creds.TokenProvider = auth.NewCachedTokenProvider(creds.TokenProvider, nil)
|
||||
trans = &authTransport{
|
||||
base: trans,
|
||||
creds: creds,
|
||||
clientUniverseDomain: opts.UniverseDomain,
|
||||
skipUniverseDomainValidation: skipUD,
|
||||
}
|
||||
}
|
||||
return trans, nil
|
||||
}
|
||||
|
||||
// defaultBaseTransport returns the base HTTP transport.
|
||||
// On App Engine, this is urlfetch.Transport.
|
||||
// Otherwise, use a default transport, taking most defaults from
|
||||
// http.DefaultTransport.
|
||||
// If TLSCertificate is available, set TLSClientConfig as well.
|
||||
func defaultBaseTransport(clientCertSource cert.Provider, dialTLSContext func(context.Context, string, string) (net.Conn, error)) http.RoundTripper {
|
||||
defaultTransport, ok := http.DefaultTransport.(*http.Transport)
|
||||
if !ok {
|
||||
defaultTransport = transport.BaseTransport()
|
||||
}
|
||||
trans := defaultTransport.Clone()
|
||||
trans.MaxIdleConnsPerHost = 100
|
||||
|
||||
if clientCertSource != nil {
|
||||
trans.TLSClientConfig = &tls.Config{
|
||||
GetClientCertificate: clientCertSource,
|
||||
}
|
||||
}
|
||||
if dialTLSContext != nil {
|
||||
// If DialTLSContext is set, TLSClientConfig wil be ignored
|
||||
trans.DialTLSContext = dialTLSContext
|
||||
}
|
||||
|
||||
// Configures the ReadIdleTimeout HTTP/2 option for the
|
||||
// transport. This allows broken idle connections to be pruned more quickly,
|
||||
// preventing the client from attempting to re-use connections that will no
|
||||
// longer work.
|
||||
http2Trans, err := http2.ConfigureTransports(trans)
|
||||
if err == nil {
|
||||
http2Trans.ReadIdleTimeout = time.Second * 31
|
||||
}
|
||||
|
||||
return trans
|
||||
}
|
||||
|
||||
type apiKeyTransport struct {
|
||||
// Key is the API Key to set on requests.
|
||||
Key string
|
||||
// Transport is the underlying HTTP transport.
|
||||
// If nil, http.DefaultTransport is used.
|
||||
Transport http.RoundTripper
|
||||
}
|
||||
|
||||
func (t *apiKeyTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
newReq := *req
|
||||
args := newReq.URL.Query()
|
||||
args.Set("key", t.Key)
|
||||
newReq.URL.RawQuery = args.Encode()
|
||||
return t.Transport.RoundTrip(&newReq)
|
||||
}
|
||||
|
||||
type headerTransport struct {
|
||||
headers http.Header
|
||||
base http.RoundTripper
|
||||
}
|
||||
|
||||
func (t *headerTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
rt := t.base
|
||||
newReq := *req
|
||||
newReq.Header = make(http.Header)
|
||||
for k, vv := range req.Header {
|
||||
newReq.Header[k] = vv
|
||||
}
|
||||
|
||||
for k, v := range t.headers {
|
||||
newReq.Header[k] = v
|
||||
}
|
||||
|
||||
return rt.RoundTrip(&newReq)
|
||||
}
|
||||
|
||||
func addOpenTelemetryTransport(trans http.RoundTripper, opts *Options) http.RoundTripper {
|
||||
if opts.DisableTelemetry {
|
||||
return trans
|
||||
}
|
||||
return otelhttp.NewTransport(trans)
|
||||
}
|
||||
|
||||
type authTransport struct {
|
||||
creds *auth.Credentials
|
||||
base http.RoundTripper
|
||||
clientUniverseDomain string
|
||||
skipUniverseDomainValidation bool
|
||||
}
|
||||
|
||||
// getClientUniverseDomain returns the default service domain for a given Cloud
|
||||
// universe, with the following precedence:
|
||||
//
|
||||
// 1. A non-empty option.WithUniverseDomain or similar client option.
|
||||
// 2. A non-empty environment variable GOOGLE_CLOUD_UNIVERSE_DOMAIN.
|
||||
// 3. The default value "googleapis.com".
|
||||
//
|
||||
// This is the universe domain configured for the client, which will be compared
|
||||
// to the universe domain that is separately configured for the credentials.
|
||||
func (t *authTransport) getClientUniverseDomain() string {
|
||||
if t.clientUniverseDomain != "" {
|
||||
return t.clientUniverseDomain
|
||||
}
|
||||
if envUD := os.Getenv(internal.UniverseDomainEnvVar); envUD != "" {
|
||||
return envUD
|
||||
}
|
||||
return internal.DefaultUniverseDomain
|
||||
}
|
||||
|
||||
// RoundTrip authorizes and authenticates the request with an
|
||||
// access token from Transport's Source. Per the RoundTripper contract we must
|
||||
// not modify the initial request, so we clone it, and we must close the body
|
||||
// on any errors that happens during our token logic.
|
||||
func (t *authTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
reqBodyClosed := false
|
||||
if req.Body != nil {
|
||||
defer func() {
|
||||
if !reqBodyClosed {
|
||||
req.Body.Close()
|
||||
}
|
||||
}()
|
||||
}
|
||||
token, err := t.creds.Token(req.Context())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !t.skipUniverseDomainValidation && token.MetadataString("auth.google.tokenSource") != "compute-metadata" {
|
||||
credentialsUniverseDomain, err := t.creds.UniverseDomain(req.Context())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := transport.ValidateUniverseDomain(t.getClientUniverseDomain(), credentialsUniverseDomain); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
req2 := req.Clone(req.Context())
|
||||
headers.SetAuthHeader(token, req2)
|
||||
reqBodyClosed = true
|
||||
return t.base.RoundTrip(req2)
|
||||
}
|
||||
Reference in New Issue
Block a user