github.com/stripe/stripe-go/v76@v76.25.0/stripe.go (about)

     1  // Package stripe provides the binding for Stripe REST APIs.
     2  package stripe
     3  
     4  import (
     5  	"bytes"
     6  	"context"
     7  	"crypto/tls"
     8  	"crypto/x509"
     9  	"encoding/json"
    10  	"errors"
    11  	"fmt"
    12  	"io"
    13  	"io/ioutil"
    14  	"math/rand"
    15  	"net/http"
    16  	"net/url"
    17  	"os/exec"
    18  	"reflect"
    19  	"regexp"
    20  	"runtime"
    21  	"strings"
    22  	"sync"
    23  	"time"
    24  
    25  	"github.com/stripe/stripe-go/v76/form"
    26  )
    27  
    28  //
    29  // Public constants
    30  //
    31  
    32  const (
    33  	// APIVersion is the currently supported API version
    34  	APIVersion string = apiVersion
    35  
    36  	// APIBackend is a constant representing the API service backend.
    37  	APIBackend SupportedBackend = "api"
    38  
    39  	// APIURL is the URL of the API service backend.
    40  	APIURL string = "https://api.stripe.com"
    41  
    42  	// ClientVersion is the version of the stripe-go library being used.
    43  	ClientVersion string = clientversion
    44  
    45  	// ConnectURL is the URL for OAuth.
    46  	ConnectURL string = "https://connect.stripe.com"
    47  
    48  	// ConnectBackend is a constant representing the connect service backend for
    49  	// OAuth.
    50  	ConnectBackend SupportedBackend = "connect"
    51  
    52  	// DefaultMaxNetworkRetries is the default maximum number of retries made
    53  	// by a Stripe client.
    54  	DefaultMaxNetworkRetries int64 = 2
    55  
    56  	// UnknownPlatform is the string returned as the system name if we couldn't get
    57  	// one from `uname`.
    58  	UnknownPlatform string = "unknown platform"
    59  
    60  	// UploadsBackend is a constant representing the uploads service backend.
    61  	UploadsBackend SupportedBackend = "uploads"
    62  
    63  	// UploadsURL is the URL of the uploads service backend.
    64  	UploadsURL string = "https://files.stripe.com"
    65  )
    66  
    67  //
    68  // Public variables
    69  //
    70  
    71  // EnableTelemetry is a global override for enabling client telemetry, which
    72  // sends request performance metrics to Stripe via the `X-Stripe-Client-Telemetry`
    73  // header. If set to true, all clients will send telemetry metrics. Defaults to
    74  // true.
    75  //
    76  // Telemetry can also be disabled on a per-client basis by instead creating a
    77  // `BackendConfig` with `EnableTelemetry: false`.
    78  var EnableTelemetry = true
    79  
    80  // Key is the Stripe API key used globally in the binding.
    81  var Key string
    82  
    83  //
    84  // Public types
    85  //
    86  
    87  // APIResponse encapsulates some common features of a response from the
    88  // Stripe API.
    89  type APIResponse struct {
    90  	// Header contain a map of all HTTP header keys to values. Its behavior and
    91  	// caveats are identical to that of http.Header.
    92  	Header http.Header
    93  
    94  	// IdempotencyKey contains the idempotency key used with this request.
    95  	// Idempotency keys are a Stripe-specific concept that helps guarantee that
    96  	// requests that fail and need to be retried are not duplicated.
    97  	IdempotencyKey string
    98  
    99  	// RawJSON contains the response body as raw bytes.
   100  	RawJSON []byte
   101  
   102  	// RequestID contains a string that uniquely identifies the Stripe request.
   103  	// Used for debugging or support purposes.
   104  	RequestID string
   105  
   106  	// Status is a status code and message. e.g. "200 OK"
   107  	Status string
   108  
   109  	// StatusCode is a status code as integer. e.g. 200
   110  	StatusCode int
   111  
   112  	duration *time.Duration
   113  }
   114  
   115  // StreamingAPIResponse encapsulates some common features of a response from the
   116  // Stripe API whose body can be streamed. This is used for "file downloads", and
   117  // the `Body` property is an io.ReadCloser, so the user can stream it to another
   118  // location such as a file or network request without buffering the entire body
   119  // into memory.
   120  type StreamingAPIResponse struct {
   121  	Header         http.Header
   122  	IdempotencyKey string
   123  	Body           io.ReadCloser
   124  	RequestID      string
   125  	Status         string
   126  	StatusCode     int
   127  	duration       *time.Duration
   128  }
   129  
   130  func newAPIResponse(res *http.Response, resBody []byte, requestDuration *time.Duration) *APIResponse {
   131  	return &APIResponse{
   132  		Header:         res.Header,
   133  		IdempotencyKey: res.Header.Get("Idempotency-Key"),
   134  		RawJSON:        resBody,
   135  		RequestID:      res.Header.Get("Request-Id"),
   136  		Status:         res.Status,
   137  		StatusCode:     res.StatusCode,
   138  		duration:       requestDuration,
   139  	}
   140  }
   141  
   142  func newStreamingAPIResponse(res *http.Response, body io.ReadCloser, requestDuration *time.Duration) *StreamingAPIResponse {
   143  	return &StreamingAPIResponse{
   144  		Header:         res.Header,
   145  		IdempotencyKey: res.Header.Get("Idempotency-Key"),
   146  		Body:           body,
   147  		RequestID:      res.Header.Get("Request-Id"),
   148  		Status:         res.Status,
   149  		StatusCode:     res.StatusCode,
   150  		duration:       requestDuration,
   151  	}
   152  }
   153  
   154  // APIResource is a type assigned to structs that may come from Stripe API
   155  // endpoints and contains facilities common to all of them.
   156  type APIResource struct {
   157  	LastResponse *APIResponse `json:"-"`
   158  }
   159  
   160  // APIStream is a type assigned to streaming responses that may come from Stripe API
   161  type APIStream struct {
   162  	LastResponse *StreamingAPIResponse
   163  }
   164  
   165  // SetLastResponse sets the HTTP response that returned the API resource.
   166  func (r *APIResource) SetLastResponse(response *APIResponse) {
   167  	r.LastResponse = response
   168  }
   169  
   170  // SetLastResponse sets the HTTP response that returned the API resource.
   171  func (r *APIStream) SetLastResponse(response *StreamingAPIResponse) {
   172  	r.LastResponse = response
   173  }
   174  
   175  // AppInfo contains information about the "app" which this integration belongs
   176  // to. This should be reserved for plugins that wish to identify themselves
   177  // with Stripe.
   178  type AppInfo struct {
   179  	Name      string `json:"name"`
   180  	PartnerID string `json:"partner_id"`
   181  	URL       string `json:"url"`
   182  	Version   string `json:"version"`
   183  }
   184  
   185  // formatUserAgent formats an AppInfo in a way that's suitable to be appended
   186  // to a User-Agent string. Note that this format is shared between all
   187  // libraries so if it's changed, it should be changed everywhere.
   188  func (a *AppInfo) formatUserAgent() string {
   189  	str := a.Name
   190  	if a.Version != "" {
   191  		str += "/" + a.Version
   192  	}
   193  	if a.URL != "" {
   194  		str += " (" + a.URL + ")"
   195  	}
   196  	return str
   197  }
   198  
   199  // Backend is an interface for making calls against a Stripe service.
   200  // This interface exists to enable mocking for during testing if needed.
   201  type Backend interface {
   202  	Call(method, path, key string, params ParamsContainer, v LastResponseSetter) error
   203  	CallStreaming(method, path, key string, params ParamsContainer, v StreamingLastResponseSetter) error
   204  	CallRaw(method, path, key string, body *form.Values, params *Params, v LastResponseSetter) error
   205  	CallMultipart(method, path, key, boundary string, body *bytes.Buffer, params *Params, v LastResponseSetter) error
   206  	SetMaxNetworkRetries(maxNetworkRetries int64)
   207  }
   208  
   209  // BackendConfig is used to configure a new Stripe backend.
   210  type BackendConfig struct {
   211  	// EnableTelemetry allows request metrics (request id and duration) to be sent
   212  	// to Stripe in subsequent requests via the `X-Stripe-Client-Telemetry` header.
   213  	//
   214  	// This value is a pointer to allow us to differentiate an unset versus
   215  	// empty value. Use stripe.Bool for an easy way to set this value.
   216  	//
   217  	// Defaults to false.
   218  	EnableTelemetry *bool
   219  
   220  	// HTTPClient is an HTTP client instance to use when making API requests.
   221  	//
   222  	// If left unset, it'll be set to a default HTTP client for the package.
   223  	HTTPClient *http.Client
   224  
   225  	// LeveledLogger is the logger that the backend will use to log errors,
   226  	// warnings, and informational messages.
   227  	//
   228  	// LeveledLoggerInterface is implemented by LeveledLogger, and one can be
   229  	// initialized at the desired level of logging.  LeveledLoggerInterface
   230  	// also provides out-of-the-box compatibility with a Logrus Logger, but may
   231  	// require a thin shim for use with other logging libraries that use less
   232  	// standard conventions like Zap.
   233  	//
   234  	// Defaults to DefaultLeveledLogger.
   235  	//
   236  	// To set a logger that logs nothing, set this to a stripe.LeveledLogger
   237  	// with a Level of LevelNull (simply setting this field to nil will not
   238  	// work).
   239  	LeveledLogger LeveledLoggerInterface
   240  
   241  	// MaxNetworkRetries sets maximum number of times that the library will
   242  	// retry requests that appear to have failed due to an intermittent
   243  	// problem.
   244  	//
   245  	// This value is a pointer to allow us to differentiate an unset versus
   246  	// empty value. Use stripe.Int64 for an easy way to set this value.
   247  	//
   248  	// Defaults to DefaultMaxNetworkRetries (2).
   249  	MaxNetworkRetries *int64
   250  
   251  	// URL is the base URL to use for API paths.
   252  	//
   253  	// This value is a pointer to allow us to differentiate an unset versus
   254  	// empty value. Use stripe.String for an easy way to set this value.
   255  	//
   256  	// If left empty, it'll be set to the default for the SupportedBackend.
   257  	URL *string
   258  }
   259  
   260  // BackendImplementation is the internal implementation for making HTTP calls
   261  // to Stripe.
   262  //
   263  // The public use of this struct is deprecated. It will be unexported in a
   264  // future version.
   265  type BackendImplementation struct {
   266  	Type              SupportedBackend
   267  	URL               string
   268  	HTTPClient        *http.Client
   269  	LeveledLogger     LeveledLoggerInterface
   270  	MaxNetworkRetries int64
   271  
   272  	enableTelemetry bool
   273  
   274  	// networkRetriesSleep indicates whether the backend should use the normal
   275  	// sleep between retries.
   276  	//
   277  	// See also SetNetworkRetriesSleep.
   278  	networkRetriesSleep bool
   279  
   280  	requestMetricsBuffer chan requestMetrics
   281  }
   282  
   283  type metricsResponseSetter struct {
   284  	LastResponseSetter
   285  	backend *BackendImplementation
   286  	params  *Params
   287  }
   288  
   289  func (s *metricsResponseSetter) SetLastResponse(response *APIResponse) {
   290  	var usage []string
   291  	if s.params != nil {
   292  		usage = s.params.usage
   293  	}
   294  	s.backend.maybeEnqueueTelemetryMetrics(response.RequestID, response.duration, usage)
   295  	s.LastResponseSetter.SetLastResponse(response)
   296  }
   297  
   298  func (s *metricsResponseSetter) UnmarshalJSON(b []byte) error {
   299  	return json.Unmarshal(b, s.LastResponseSetter)
   300  }
   301  
   302  type streamingLastResponseSetterWrapper struct {
   303  	StreamingLastResponseSetter
   304  	f func(*StreamingAPIResponse)
   305  }
   306  
   307  func (l *streamingLastResponseSetterWrapper) SetLastResponse(response *StreamingAPIResponse) {
   308  	l.f(response)
   309  	l.StreamingLastResponseSetter.SetLastResponse(response)
   310  }
   311  func (l *streamingLastResponseSetterWrapper) UnmarshalJSON(b []byte) error {
   312  	return json.Unmarshal(b, l.StreamingLastResponseSetter)
   313  }
   314  
   315  func extractParams(params ParamsContainer) (*form.Values, *Params, error) {
   316  	var formValues *form.Values
   317  	var commonParams *Params
   318  
   319  	if params != nil {
   320  		// This is a little unfortunate, but Go makes it impossible to compare
   321  		// an interface value to nil without the use of the reflect package and
   322  		// its true disciples insist that this is a feature and not a bug.
   323  		//
   324  		// Here we do invoke reflect because (1) we have to reflect anyway to
   325  		// use encode with the form package, and (2) the corresponding removal
   326  		// of boilerplate that this enables makes the small performance penalty
   327  		// worth it.
   328  		reflectValue := reflect.ValueOf(params)
   329  
   330  		if reflectValue.Kind() == reflect.Ptr && !reflectValue.IsNil() {
   331  			commonParams = params.GetParams()
   332  
   333  			if !reflectValue.Elem().FieldByName("Metadata").IsZero() {
   334  				if commonParams.Metadata != nil {
   335  					return nil, nil, fmt.Errorf("You cannot specify both the (deprecated) .Params.Metadata and .Metadata in %s", reflectValue.Elem().Type().Name())
   336  				}
   337  			}
   338  
   339  			if !reflectValue.Elem().FieldByName("Expand").IsZero() {
   340  				if commonParams.Expand != nil {
   341  					return nil, nil, fmt.Errorf("You cannot specify both the (deprecated) .Params.Expand and .Expand in %s", reflectValue.Elem().Type().Name())
   342  				}
   343  			}
   344  
   345  			formValues = &form.Values{}
   346  			form.AppendTo(formValues, params)
   347  		}
   348  	}
   349  	return formValues, commonParams, nil
   350  }
   351  
   352  // Call is the Backend.Call implementation for invoking Stripe APIs.
   353  func (s *BackendImplementation) Call(method, path, key string, params ParamsContainer, v LastResponseSetter) error {
   354  	body, commonParams, err := extractParams(params)
   355  	if err != nil {
   356  		return err
   357  	}
   358  	return s.CallRaw(method, path, key, body, commonParams, v)
   359  }
   360  
   361  // CallStreaming is the Backend.Call implementation for invoking Stripe APIs
   362  // without buffering the response into memory.
   363  func (s *BackendImplementation) CallStreaming(method, path, key string, params ParamsContainer, v StreamingLastResponseSetter) error {
   364  	formValues, commonParams, err := extractParams(params)
   365  	if err != nil {
   366  		return err
   367  	}
   368  
   369  	var body string
   370  	if formValues != nil && !formValues.Empty() {
   371  		body = formValues.Encode()
   372  
   373  		// On `GET`, move the payload into the URL
   374  		if method == http.MethodGet {
   375  			path += "?" + body
   376  			body = ""
   377  		}
   378  	}
   379  	bodyBuffer := bytes.NewBufferString(body)
   380  
   381  	req, err := s.NewRequest(method, path, key, "application/x-www-form-urlencoded", commonParams)
   382  	if err != nil {
   383  		return err
   384  	}
   385  
   386  	responseSetter := streamingLastResponseSetterWrapper{
   387  		v,
   388  		func(response *StreamingAPIResponse) {
   389  			var usage []string
   390  			if commonParams != nil {
   391  				usage = commonParams.usage
   392  			}
   393  			s.maybeEnqueueTelemetryMetrics(response.RequestID, response.duration, usage)
   394  		},
   395  	}
   396  
   397  	if err := s.DoStreaming(req, bodyBuffer, &responseSetter); err != nil {
   398  		return err
   399  	}
   400  
   401  	return nil
   402  }
   403  
   404  // CallMultipart is the Backend.CallMultipart implementation for invoking Stripe APIs.
   405  func (s *BackendImplementation) CallMultipart(method, path, key, boundary string, body *bytes.Buffer, params *Params, v LastResponseSetter) error {
   406  	contentType := "multipart/form-data; boundary=" + boundary
   407  
   408  	req, err := s.NewRequest(method, path, key, contentType, params)
   409  	if err != nil {
   410  		return err
   411  	}
   412  
   413  	if err := s.Do(req, body, v); err != nil {
   414  		return err
   415  	}
   416  
   417  	return nil
   418  }
   419  
   420  // CallRaw is the implementation for invoking Stripe APIs internally without a backend.
   421  func (s *BackendImplementation) CallRaw(method, path, key string, form *form.Values, params *Params, v LastResponseSetter) error {
   422  	var body string
   423  	if form != nil && !form.Empty() {
   424  		body = form.Encode()
   425  
   426  		// On `GET`, move the payload into the URL
   427  		if method == http.MethodGet {
   428  			path += "?" + body
   429  			body = ""
   430  		}
   431  	}
   432  	bodyBuffer := bytes.NewBufferString(body)
   433  
   434  	req, err := s.NewRequest(method, path, key, "application/x-www-form-urlencoded", params)
   435  	if err != nil {
   436  		return err
   437  	}
   438  
   439  	responseSetter := metricsResponseSetter{
   440  		LastResponseSetter: v,
   441  		backend:            s,
   442  		params:             params,
   443  	}
   444  
   445  	if err := s.Do(req, bodyBuffer, &responseSetter); err != nil {
   446  		return err
   447  	}
   448  
   449  	return nil
   450  }
   451  
   452  // NewRequest is used by Call to generate an http.Request. It handles encoding
   453  // parameters and attaching the appropriate headers.
   454  func (s *BackendImplementation) NewRequest(method, path, key, contentType string, params *Params) (*http.Request, error) {
   455  	if !strings.HasPrefix(path, "/") {
   456  		path = "/" + path
   457  	}
   458  
   459  	path = s.URL + path
   460  
   461  	// Body is set later by `Do`.
   462  	req, err := http.NewRequest(method, path, nil)
   463  	if err != nil {
   464  		s.LeveledLogger.Errorf("Cannot create Stripe request: %v", err)
   465  		return nil, err
   466  	}
   467  
   468  	authorization := "Bearer " + key
   469  
   470  	req.Header.Add("Authorization", authorization)
   471  	req.Header.Add("Content-Type", contentType)
   472  	req.Header.Add("Stripe-Version", APIVersion)
   473  	req.Header.Add("User-Agent", encodedUserAgent)
   474  	req.Header.Add("X-Stripe-Client-User-Agent", getEncodedStripeUserAgent())
   475  
   476  	if params != nil {
   477  		if params.Context != nil {
   478  			req = req.WithContext(params.Context)
   479  		}
   480  
   481  		if params.IdempotencyKey != nil {
   482  			idempotencyKey := strings.TrimSpace(*params.IdempotencyKey)
   483  			if len(idempotencyKey) > 255 {
   484  				return nil, errors.New("cannot use an idempotency key longer than 255 characters")
   485  			}
   486  
   487  			req.Header.Add("Idempotency-Key", idempotencyKey)
   488  		} else if isHTTPWriteMethod(method) {
   489  			req.Header.Add("Idempotency-Key", NewIdempotencyKey())
   490  		}
   491  
   492  		if params.StripeAccount != nil {
   493  			req.Header.Add("Stripe-Account", strings.TrimSpace(*params.StripeAccount))
   494  		}
   495  
   496  		for k, v := range params.Headers {
   497  			for _, line := range v {
   498  				// Use Set to override the default value possibly set before
   499  				req.Header.Set(k, line)
   500  			}
   501  		}
   502  	}
   503  
   504  	return req, nil
   505  }
   506  
   507  func (s *BackendImplementation) maybeSetTelemetryHeader(req *http.Request) {
   508  	if s.enableTelemetry {
   509  		select {
   510  		case metrics := <-s.requestMetricsBuffer:
   511  			metricsJSON, err := json.Marshal(&requestTelemetry{LastRequestMetrics: metrics})
   512  			if err == nil {
   513  				req.Header.Set("X-Stripe-Client-Telemetry", string(metricsJSON))
   514  			} else {
   515  				s.LeveledLogger.Warnf("Unable to encode client telemetry: %v", err)
   516  			}
   517  		default:
   518  			// There are no metrics available, so don't send any.
   519  			// This default case  needs to be here to prevent Do from blocking on an
   520  			// empty requestMetricsBuffer.
   521  		}
   522  	}
   523  }
   524  
   525  func (s *BackendImplementation) maybeEnqueueTelemetryMetrics(requestID string, requestDuration *time.Duration, usage []string) {
   526  	if !s.enableTelemetry || requestID == "" {
   527  		return
   528  	}
   529  	// If there's no duration to report and no usage to report, don't bother
   530  	if requestDuration == nil && len(usage) == 0 {
   531  		return
   532  	}
   533  	metrics := requestMetrics{
   534  		RequestID: requestID,
   535  	}
   536  	if requestDuration != nil {
   537  		requestDurationMS := int(*requestDuration / time.Millisecond)
   538  		metrics.RequestDurationMS = &requestDurationMS
   539  	}
   540  	if len(usage) > 0 {
   541  		metrics.Usage = usage
   542  	}
   543  	select {
   544  	case s.requestMetricsBuffer <- metrics:
   545  	default:
   546  	}
   547  }
   548  
   549  func resetBodyReader(body *bytes.Buffer, req *http.Request) {
   550  	// This might look a little strange, but we set the request's body
   551  	// outside of `NewRequest` so that we can get a fresh version every
   552  	// time.
   553  	//
   554  	// The background is that back in the era of old style HTTP, it was
   555  	// safe to reuse `Request` objects, but with the addition of HTTP/2,
   556  	// it's now only sometimes safe. Reusing a `Request` with a body will
   557  	// break.
   558  	//
   559  	// See some details here:
   560  	//
   561  	//     https://github.com/golang/go/issues/19653#issuecomment-341539160
   562  	//
   563  	// And our original bug report here:
   564  	//
   565  	//     https://github.com/stripe/stripe-go/issues/642
   566  	//
   567  	// To workaround the problem, we put a fresh `Body` onto the `Request`
   568  	// every time we execute it, and this seems to empirically resolve the
   569  	// problem.
   570  	if body != nil {
   571  		// We can safely reuse the same buffer that we used to encode our body,
   572  		// but return a new reader to it everytime so that each read is from
   573  		// the beginning.
   574  		reader := bytes.NewReader(body.Bytes())
   575  
   576  		req.Body = nopReadCloser{reader}
   577  
   578  		// And also add the same thing to `Request.GetBody`, which allows
   579  		// `net/http` to get a new body in cases like a redirect. This is
   580  		// usually not used, but it doesn't hurt to set it in case it's
   581  		// needed. See:
   582  		//
   583  		//     https://github.com/stripe/stripe-go/issues/710
   584  		//
   585  		req.GetBody = func() (io.ReadCloser, error) {
   586  			reader := bytes.NewReader(body.Bytes())
   587  			return nopReadCloser{reader}, nil
   588  		}
   589  	}
   590  }
   591  
   592  // requestWithRetriesAndTelemetry uses s.HTTPClient to make an HTTP request,
   593  // and handles retries, telemetry, and emitting log statements.  It attempts to
   594  // avoid processing the *result* of the HTTP request. It receives a
   595  // "handleResponse" func from the caller, and it defers to that to determine
   596  // whether the request was a failure or success, and to convert the
   597  // response/error into the appropriate type of error or an appropriate result
   598  // type.
   599  func (s *BackendImplementation) requestWithRetriesAndTelemetry(
   600  	req *http.Request,
   601  	body *bytes.Buffer,
   602  	handleResponse func(*http.Response, error) (interface{}, error),
   603  ) (*http.Response, interface{}, *time.Duration, error) {
   604  	s.LeveledLogger.Infof("Requesting %v %v%v", req.Method, req.URL.Host, req.URL.Path)
   605  	s.maybeSetTelemetryHeader(req)
   606  	var resp *http.Response
   607  	var err error
   608  	var requestDuration time.Duration
   609  	var result interface{}
   610  	for retry := 0; ; {
   611  		start := time.Now()
   612  		resetBodyReader(body, req)
   613  
   614  		resp, err = s.HTTPClient.Do(req)
   615  
   616  		requestDuration = time.Since(start)
   617  		s.LeveledLogger.Infof("Request completed in %v (retry: %v)", requestDuration, retry)
   618  
   619  		result, err = handleResponse(resp, err)
   620  
   621  		// If the response was okay, or an error that shouldn't be retried,
   622  		// we're done, and it's safe to leave the retry loop.
   623  		shouldRetry, noRetryReason := s.shouldRetry(err, req, resp, retry)
   624  
   625  		if !shouldRetry {
   626  			s.LeveledLogger.Infof("Not retrying request: %v", noRetryReason)
   627  			break
   628  		}
   629  
   630  		sleepDuration := s.sleepTime(retry)
   631  		retry++
   632  
   633  		s.LeveledLogger.Warnf("Initiating retry %v for request %v %v%v after sleeping %v",
   634  			retry, req.Method, req.URL.Host, req.URL.Path, sleepDuration)
   635  
   636  		time.Sleep(sleepDuration)
   637  	}
   638  
   639  	if err != nil {
   640  		return nil, nil, nil, err
   641  	}
   642  
   643  	return resp, result, &requestDuration, nil
   644  }
   645  
   646  func (s *BackendImplementation) logError(statusCode int, err error) {
   647  	if stripeErr, ok := err.(*Error); ok {
   648  		// The Stripe API makes a distinction between errors that were
   649  		// caused by invalid parameters or something else versus those
   650  		// that occurred *despite* valid parameters, the latter coming
   651  		// back with status 402.
   652  		//
   653  		// On a 402, log to info so as to not make an integration's log
   654  		// noisy with error messages that they don't have much control
   655  		// over.
   656  		//
   657  		// Note I use the constant 402 instead of an `http.Status*`
   658  		// constant because technically 402 is "Payment required". The
   659  		// Stripe API doesn't comply to the letter of the specification
   660  		// and uses it in a broader sense.
   661  		if statusCode == 402 {
   662  			s.LeveledLogger.Infof("User-compelled request error from Stripe (status %v): %v",
   663  				statusCode, stripeErr.redact())
   664  		} else {
   665  			s.LeveledLogger.Errorf("Request error from Stripe (status %v): %v",
   666  				statusCode, stripeErr.redact())
   667  		}
   668  	} else {
   669  		s.LeveledLogger.Errorf("Error decoding error from Stripe: %v", err)
   670  	}
   671  }
   672  
   673  // DoStreaming is used by CallStreaming to execute an API request. It uses the
   674  // backend's HTTP client to execure the request.  In successful cases, it sets
   675  // a StreamingLastResponse onto v, but in unsuccessful cases handles unmarshaling
   676  // errors returned by the API.
   677  func (s *BackendImplementation) DoStreaming(req *http.Request, body *bytes.Buffer, v StreamingLastResponseSetter) error {
   678  	handleResponse := func(res *http.Response, err error) (interface{}, error) {
   679  
   680  		// Some sort of connection error
   681  		if err != nil {
   682  			s.LeveledLogger.Errorf("Request failed with error: %v", err)
   683  			return res.Body, err
   684  		}
   685  
   686  		// Successful response, return the body ReadCloser
   687  		if res.StatusCode < 400 {
   688  			return res.Body, err
   689  		}
   690  
   691  		// Failure: try and parse the json of the response
   692  		// when logging the error
   693  		var resBody []byte
   694  		resBody, err = ioutil.ReadAll(res.Body)
   695  		res.Body.Close()
   696  		if err == nil {
   697  			err = s.ResponseToError(res, resBody)
   698  		} else {
   699  			s.logError(res.StatusCode, err)
   700  		}
   701  
   702  		return res.Body, err
   703  	}
   704  
   705  	resp, result, requestDuration, err := s.requestWithRetriesAndTelemetry(req, body, handleResponse)
   706  	if err != nil {
   707  		return err
   708  	}
   709  	v.SetLastResponse(newStreamingAPIResponse(resp, result.(io.ReadCloser), requestDuration))
   710  	return nil
   711  }
   712  
   713  // Do is used by Call to execute an API request and parse the response. It uses
   714  // the backend's HTTP client to execute the request and unmarshals the response
   715  // into v. It also handles unmarshaling errors returned by the API.
   716  func (s *BackendImplementation) Do(req *http.Request, body *bytes.Buffer, v LastResponseSetter) error {
   717  	handleResponse := func(res *http.Response, err error) (interface{}, error) {
   718  		var resBody []byte
   719  		if err == nil {
   720  			resBody, err = ioutil.ReadAll(res.Body)
   721  			res.Body.Close()
   722  		}
   723  
   724  		if err != nil {
   725  			s.LeveledLogger.Errorf("Request failed with error: %v", err)
   726  		} else if res.StatusCode >= 400 {
   727  			err = s.ResponseToError(res, resBody)
   728  
   729  			s.logError(res.StatusCode, err)
   730  		}
   731  
   732  		return resBody, err
   733  	}
   734  
   735  	res, result, requestDuration, err := s.requestWithRetriesAndTelemetry(req, body, handleResponse)
   736  	if err != nil {
   737  		return err
   738  	}
   739  	resBody := result.([]byte)
   740  	s.LeveledLogger.Debugf("Response: %s", string(resBody))
   741  
   742  	err = s.UnmarshalJSONVerbose(res.StatusCode, resBody, v)
   743  	v.SetLastResponse(newAPIResponse(res, resBody, requestDuration))
   744  	return err
   745  }
   746  
   747  // ResponseToError converts a stripe response to an Error.
   748  func (s *BackendImplementation) ResponseToError(res *http.Response, resBody []byte) error {
   749  	var raw rawError
   750  	if s.Type == ConnectBackend {
   751  		// If this is an OAuth request, deserialize as Error because OAuth errors
   752  		// are a different shape from the standard API errors.
   753  		var topLevelError Error
   754  		if err := s.UnmarshalJSONVerbose(res.StatusCode, resBody, &topLevelError); err != nil {
   755  			return err
   756  		}
   757  		raw.Error = &topLevelError
   758  	} else {
   759  		if err := s.UnmarshalJSONVerbose(res.StatusCode, resBody, &raw); err != nil {
   760  			return err
   761  		}
   762  	}
   763  
   764  	// no error in resBody
   765  	if raw.Error == nil {
   766  		err := errors.New(string(resBody))
   767  		return err
   768  	}
   769  	raw.Error.HTTPStatusCode = res.StatusCode
   770  	raw.Error.RequestID = res.Header.Get("Request-Id")
   771  
   772  	var typedError error
   773  	switch raw.Error.Type {
   774  	case ErrorTypeAPI:
   775  		typedError = &APIError{stripeErr: raw.Error}
   776  	case ErrorTypeCard:
   777  		cardErr := &CardError{stripeErr: raw.Error}
   778  
   779  		// `DeclineCode` was traditionally only available on `CardError`, but
   780  		// we ended up moving it to the top-level error as well. However, keep
   781  		// it on `CardError` for backwards compatibility.
   782  		if raw.Error.DeclineCode != "" {
   783  			cardErr.DeclineCode = raw.Error.DeclineCode
   784  		}
   785  
   786  		typedError = cardErr
   787  	case ErrorTypeIdempotency:
   788  		typedError = &IdempotencyError{stripeErr: raw.Error}
   789  	case ErrorTypeInvalidRequest:
   790  		typedError = &InvalidRequestError{stripeErr: raw.Error}
   791  	}
   792  	raw.Error.Err = typedError
   793  
   794  	raw.Error.SetLastResponse(newAPIResponse(res, resBody, nil))
   795  
   796  	return raw.Error
   797  }
   798  
   799  // SetMaxNetworkRetries sets max number of retries on failed requests
   800  //
   801  // This function is deprecated. Please use GetBackendWithConfig instead.
   802  func (s *BackendImplementation) SetMaxNetworkRetries(maxNetworkRetries int64) {
   803  	s.MaxNetworkRetries = maxNetworkRetries
   804  }
   805  
   806  // SetNetworkRetriesSleep allows the normal sleep between network retries to be
   807  // enabled or disabled.
   808  //
   809  // This function is available for internal testing only and should never be
   810  // used in production.
   811  func (s *BackendImplementation) SetNetworkRetriesSleep(sleep bool) {
   812  	s.networkRetriesSleep = sleep
   813  }
   814  
   815  // UnmarshalJSONVerbose unmarshals JSON, but in case of a failure logs and
   816  // produces a more descriptive error.
   817  func (s *BackendImplementation) UnmarshalJSONVerbose(statusCode int, body []byte, v interface{}) error {
   818  	err := json.Unmarshal(body, v)
   819  	if err != nil {
   820  		// If we got invalid JSON back then something totally unexpected is
   821  		// happening (caused by a bug on the server side). Put a sample of the
   822  		// response body into the error message so we can get a better feel for
   823  		// what the problem was.
   824  		bodySample := string(body)
   825  		if len(bodySample) > 500 {
   826  			bodySample = bodySample[0:500] + " ..."
   827  		}
   828  
   829  		// Make sure a multi-line response ends up all on one line
   830  		bodySample = strings.Replace(bodySample, "\n", "\\n", -1)
   831  
   832  		newErr := fmt.Errorf("Couldn't deserialize JSON (response status: %v, body sample: '%s'): %v",
   833  			statusCode, bodySample, err)
   834  		s.LeveledLogger.Errorf("%s", newErr.Error())
   835  		return newErr
   836  	}
   837  
   838  	return nil
   839  }
   840  
   841  // Regular expressions used to match a few error types that we know we don't
   842  // want to retry. Unfortunately these errors aren't typed so we match on the
   843  // error's message.
   844  var (
   845  	redirectsErrorRE = regexp.MustCompile(`stopped after \d+ redirects\z`)
   846  	schemeErrorRE    = regexp.MustCompile(`unsupported protocol scheme`)
   847  )
   848  
   849  // Checks if an error is a problem that we should retry on. This includes both
   850  // socket errors that may represent an intermittent problem and some special
   851  // HTTP statuses.
   852  //
   853  // Returns a boolean indicating whether a client should retry. If false, a
   854  // second string parameter is also returned with a short message indicating why
   855  // no retry should occur. This can be used for logging/informational purposes.
   856  func (s *BackendImplementation) shouldRetry(err error, req *http.Request, resp *http.Response, numRetries int) (bool, string) {
   857  	if numRetries >= int(s.MaxNetworkRetries) {
   858  		return false, "max retries exceeded"
   859  	}
   860  
   861  	stripeErr, _ := err.(*Error)
   862  
   863  	// Don't retry if the context was canceled or its deadline was exceeded.
   864  	if req.Context() != nil && req.Context().Err() != nil {
   865  		switch req.Context().Err() {
   866  		case context.Canceled:
   867  			return false, "context canceled"
   868  		case context.DeadlineExceeded:
   869  			return false, "context deadline exceeded"
   870  		default:
   871  			return false, fmt.Sprintf("unknown context error: %v", req.Context().Err())
   872  		}
   873  	}
   874  
   875  	// We retry most errors that come out of HTTP requests except for a curated
   876  	// list that we know not to be retryable. This list is probably not
   877  	// exhaustive, so it'd be okay to add new errors to it. It'd also be okay to
   878  	// flip this to an inverted strategy of retrying only errors that we know
   879  	// to be retryable in a future refactor, if a good methodology is found for
   880  	// identifying that full set of errors.
   881  	if stripeErr == nil && err != nil {
   882  		if urlErr, ok := err.(*url.Error); ok {
   883  			// Don't retry too many redirects.
   884  			if redirectsErrorRE.MatchString(urlErr.Error()) {
   885  				return false, urlErr.Error()
   886  			}
   887  
   888  			// Don't retry invalid protocol scheme.
   889  			if schemeErrorRE.MatchString(urlErr.Error()) {
   890  				return false, urlErr.Error()
   891  			}
   892  
   893  			// Don't retry TLS certificate validation problems.
   894  			if _, ok := urlErr.Err.(x509.UnknownAuthorityError); ok {
   895  				return false, urlErr.Error()
   896  			}
   897  		}
   898  
   899  		// Do retry every other type of non-Stripe error.
   900  		return true, ""
   901  	}
   902  
   903  	// The API may ask us not to retry (e.g. if doing so would be a no-op), or
   904  	// advise us to retry (e.g. in cases of lock timeouts). Defer to those
   905  	// instructions if given.
   906  	if resp.Header.Get("Stripe-Should-Retry") == "false" {
   907  		return false, "`Stripe-Should-Retry` header returned `false`"
   908  	}
   909  	if resp.Header.Get("Stripe-Should-Retry") == "true" {
   910  		return true, ""
   911  	}
   912  
   913  	// 409 Conflict
   914  	if resp.StatusCode == http.StatusConflict {
   915  		return true, ""
   916  	}
   917  
   918  	// 429 Too Many Requests
   919  	//
   920  	// There are a few different problems that can lead to a 429. The most
   921  	// common is rate limiting, on which we *don't* want to retry because
   922  	// that'd likely contribute to more contention problems. However, some 429s
   923  	// are lock timeouts, which is when a request conflicted with another
   924  	// request or an internal process on some particular object. These 429s are
   925  	// safe to retry.
   926  	if resp.StatusCode == http.StatusTooManyRequests {
   927  		if stripeErr != nil && stripeErr.Code == ErrorCodeLockTimeout {
   928  			return true, ""
   929  		}
   930  	}
   931  
   932  	// 500 Internal Server Error
   933  	//
   934  	// We only bother retrying these for non-POST requests. POSTs end up being
   935  	// cached by the idempotency layer so there's no purpose in retrying them.
   936  	if resp.StatusCode >= http.StatusInternalServerError && req.Method != http.MethodPost {
   937  		return true, ""
   938  	}
   939  
   940  	// 503 Service Unavailable
   941  	if resp.StatusCode == http.StatusServiceUnavailable {
   942  		return true, ""
   943  	}
   944  
   945  	return false, "response not known to be safe for retry"
   946  }
   947  
   948  // sleepTime calculates sleeping/delay time in milliseconds between failure and a new one request.
   949  func (s *BackendImplementation) sleepTime(numRetries int) time.Duration {
   950  	// We disable sleeping in some cases for tests.
   951  	if !s.networkRetriesSleep {
   952  		return 0 * time.Second
   953  	}
   954  
   955  	// Apply exponential backoff with minNetworkRetriesDelay on the
   956  	// number of num_retries so far as inputs.
   957  	delay := minNetworkRetriesDelay + minNetworkRetriesDelay*time.Duration(numRetries*numRetries)
   958  
   959  	// Do not allow the number to exceed maxNetworkRetriesDelay.
   960  	if delay > maxNetworkRetriesDelay {
   961  		delay = maxNetworkRetriesDelay
   962  	}
   963  
   964  	// Apply some jitter by randomizing the value in the range of 75%-100%.
   965  	jitter := rand.Int63n(int64(delay / 4))
   966  	delay -= time.Duration(jitter)
   967  
   968  	// But never sleep less than the base sleep seconds.
   969  	if delay < minNetworkRetriesDelay {
   970  		delay = minNetworkRetriesDelay
   971  	}
   972  
   973  	return delay
   974  }
   975  
   976  // Backends are the currently supported endpoints.
   977  type Backends struct {
   978  	API, Connect, Uploads Backend
   979  	mu                    sync.RWMutex
   980  }
   981  
   982  // LastResponseSetter defines a type that contains an HTTP response from a Stripe
   983  // API endpoint.
   984  type LastResponseSetter interface {
   985  	SetLastResponse(response *APIResponse)
   986  }
   987  
   988  // StreamingLastResponseSetter defines a type that contains an HTTP response from a Stripe
   989  // API endpoint.
   990  type StreamingLastResponseSetter interface {
   991  	SetLastResponse(response *StreamingAPIResponse)
   992  }
   993  
   994  // SupportedBackend is an enumeration of supported Stripe endpoints.
   995  // Currently supported values are "api" and "uploads".
   996  type SupportedBackend string
   997  
   998  //
   999  // Public functions
  1000  //
  1001  
  1002  // Bool returns a pointer to the bool value passed in.
  1003  func Bool(v bool) *bool {
  1004  	return &v
  1005  }
  1006  
  1007  // BoolValue returns the value of the bool pointer passed in or
  1008  // false if the pointer is nil.
  1009  func BoolValue(v *bool) bool {
  1010  	if v != nil {
  1011  		return *v
  1012  	}
  1013  	return false
  1014  }
  1015  
  1016  // BoolSlice returns a slice of bool pointers given a slice of bools.
  1017  func BoolSlice(v []bool) []*bool {
  1018  	out := make([]*bool, len(v))
  1019  	for i := range v {
  1020  		out[i] = &v[i]
  1021  	}
  1022  	return out
  1023  }
  1024  
  1025  // Float64 returns a pointer to the float64 value passed in.
  1026  func Float64(v float64) *float64 {
  1027  	return &v
  1028  }
  1029  
  1030  // Float64Value returns the value of the float64 pointer passed in or
  1031  // 0 if the pointer is nil.
  1032  func Float64Value(v *float64) float64 {
  1033  	if v != nil {
  1034  		return *v
  1035  	}
  1036  	return 0
  1037  }
  1038  
  1039  // Float64Slice returns a slice of float64 pointers given a slice of float64s.
  1040  func Float64Slice(v []float64) []*float64 {
  1041  	out := make([]*float64, len(v))
  1042  	for i := range v {
  1043  		out[i] = &v[i]
  1044  	}
  1045  	return out
  1046  }
  1047  
  1048  // FormatURLPath takes a format string (of the kind used in the fmt package)
  1049  // representing a URL path with a number of parameters that belong in the path
  1050  // and returns a formatted string.
  1051  //
  1052  // This is mostly a pass through to Sprintf. It exists to make it
  1053  // it impossible to accidentally provide a parameter type that would be
  1054  // formatted improperly; for example, a string pointer instead of a string.
  1055  //
  1056  // It also URL-escapes every given parameter. This usually isn't necessary for
  1057  // a standard Stripe ID, but is needed in places where user-provided IDs are
  1058  // allowed, like in coupons or plans. We apply it broadly for extra safety.
  1059  func FormatURLPath(format string, params ...string) string {
  1060  	// Convert parameters to interface{} and URL-escape them
  1061  	untypedParams := make([]interface{}, len(params))
  1062  	for i, param := range params {
  1063  		untypedParams[i] = interface{}(url.QueryEscape(param))
  1064  	}
  1065  
  1066  	return fmt.Sprintf(format, untypedParams...)
  1067  }
  1068  
  1069  // GetBackend returns one of the library's supported backends based off of the
  1070  // given argument.
  1071  //
  1072  // It returns an existing default backend if one's already been created.
  1073  func GetBackend(backendType SupportedBackend) Backend {
  1074  	var backend Backend
  1075  
  1076  	backends.mu.RLock()
  1077  	switch backendType {
  1078  	case APIBackend:
  1079  		backend = backends.API
  1080  	case ConnectBackend:
  1081  		backend = backends.Connect
  1082  	case UploadsBackend:
  1083  		backend = backends.Uploads
  1084  	}
  1085  	backends.mu.RUnlock()
  1086  	if backend != nil {
  1087  		return backend
  1088  	}
  1089  
  1090  	backend = GetBackendWithConfig(
  1091  		backendType,
  1092  		&BackendConfig{
  1093  			HTTPClient:        httpClient,
  1094  			LeveledLogger:     nil, // Set by GetBackendWithConfiguation when nil
  1095  			MaxNetworkRetries: nil, // Set by GetBackendWithConfiguation when nil
  1096  			URL:               nil, // Set by GetBackendWithConfiguation when nil
  1097  		},
  1098  	)
  1099  
  1100  	SetBackend(backendType, backend)
  1101  
  1102  	return backend
  1103  }
  1104  
  1105  // GetBackendWithConfig is the same as GetBackend except that it can be given a
  1106  // configuration struct that will configure certain aspects of the backend
  1107  // that's return.
  1108  func GetBackendWithConfig(backendType SupportedBackend, config *BackendConfig) Backend {
  1109  	if config.HTTPClient == nil {
  1110  		config.HTTPClient = httpClient
  1111  	}
  1112  
  1113  	if config.LeveledLogger == nil {
  1114  		config.LeveledLogger = DefaultLeveledLogger
  1115  	}
  1116  
  1117  	if config.MaxNetworkRetries == nil {
  1118  		config.MaxNetworkRetries = Int64(DefaultMaxNetworkRetries)
  1119  	}
  1120  
  1121  	switch backendType {
  1122  	case APIBackend:
  1123  		if config.URL == nil {
  1124  			config.URL = String(APIURL)
  1125  		}
  1126  
  1127  		config.URL = String(normalizeURL(*config.URL))
  1128  
  1129  		return newBackendImplementation(backendType, config)
  1130  
  1131  	case UploadsBackend:
  1132  		if config.URL == nil {
  1133  			config.URL = String(UploadsURL)
  1134  		}
  1135  
  1136  		config.URL = String(normalizeURL(*config.URL))
  1137  
  1138  		return newBackendImplementation(backendType, config)
  1139  
  1140  	case ConnectBackend:
  1141  		if config.URL == nil {
  1142  			config.URL = String(ConnectURL)
  1143  		}
  1144  
  1145  		config.URL = String(normalizeURL(*config.URL))
  1146  
  1147  		return newBackendImplementation(backendType, config)
  1148  	}
  1149  
  1150  	return nil
  1151  }
  1152  
  1153  // Int64 returns a pointer to the int64 value passed in.
  1154  func Int64(v int64) *int64 {
  1155  	return &v
  1156  }
  1157  
  1158  // Int64Value returns the value of the int64 pointer passed in or
  1159  // 0 if the pointer is nil.
  1160  func Int64Value(v *int64) int64 {
  1161  	if v != nil {
  1162  		return *v
  1163  	}
  1164  	return 0
  1165  }
  1166  
  1167  // Int64Slice returns a slice of int64 pointers given a slice of int64s.
  1168  func Int64Slice(v []int64) []*int64 {
  1169  	out := make([]*int64, len(v))
  1170  	for i := range v {
  1171  		out[i] = &v[i]
  1172  	}
  1173  	return out
  1174  }
  1175  
  1176  // NewBackends creates a new set of backends with the given HTTP client.
  1177  func NewBackends(httpClient *http.Client) *Backends {
  1178  	apiConfig := &BackendConfig{HTTPClient: httpClient}
  1179  	connectConfig := &BackendConfig{HTTPClient: httpClient}
  1180  	uploadConfig := &BackendConfig{HTTPClient: httpClient}
  1181  	return &Backends{
  1182  		API:     GetBackendWithConfig(APIBackend, apiConfig),
  1183  		Connect: GetBackendWithConfig(ConnectBackend, connectConfig),
  1184  		Uploads: GetBackendWithConfig(UploadsBackend, uploadConfig),
  1185  	}
  1186  }
  1187  
  1188  // NewBackendsWithConfig creates a new set of backends with the given config for all backends.
  1189  // Useful for setting up client with a custom logger and http client.
  1190  func NewBackendsWithConfig(config *BackendConfig) *Backends {
  1191  	return &Backends{
  1192  		API:     GetBackendWithConfig(APIBackend, config),
  1193  		Connect: GetBackendWithConfig(ConnectBackend, config),
  1194  		Uploads: GetBackendWithConfig(UploadsBackend, config),
  1195  	}
  1196  }
  1197  
  1198  // ParseID attempts to parse a string scalar from a given JSON value which is
  1199  // still encoded as []byte. If the value was a string, it returns the string
  1200  // along with true as the second return value. If not, false is returned as the
  1201  // second return value.
  1202  //
  1203  // The purpose of this function is to detect whether a given value in a
  1204  // response from the Stripe API is a string ID or an expanded object.
  1205  func ParseID(data []byte) (string, bool) {
  1206  	s := string(data)
  1207  
  1208  	if !strings.HasPrefix(s, "\"") {
  1209  		return "", false
  1210  	}
  1211  
  1212  	if !strings.HasSuffix(s, "\"") {
  1213  		return "", false
  1214  	}
  1215  
  1216  	// Edge case that should never happen; found via fuzzing
  1217  	if s == "\"" {
  1218  		return "", false
  1219  	}
  1220  
  1221  	return s[1 : len(s)-1], true
  1222  }
  1223  
  1224  // SetAppInfo sets app information. See AppInfo.
  1225  func SetAppInfo(info *AppInfo) {
  1226  	if info != nil && info.Name == "" {
  1227  		panic(fmt.Errorf("App info name cannot be empty"))
  1228  	}
  1229  	appInfo = info
  1230  
  1231  	// This is run in init, but we need to reinitialize it now that we have
  1232  	// some app info.
  1233  	initUserAgent()
  1234  }
  1235  
  1236  // SetBackend sets the backend used in the binding.
  1237  func SetBackend(backend SupportedBackend, b Backend) {
  1238  	backends.mu.Lock()
  1239  	defer backends.mu.Unlock()
  1240  
  1241  	switch backend {
  1242  	case APIBackend:
  1243  		backends.API = b
  1244  	case ConnectBackend:
  1245  		backends.Connect = b
  1246  	case UploadsBackend:
  1247  		backends.Uploads = b
  1248  	}
  1249  }
  1250  
  1251  // SetHTTPClient overrides the default HTTP client.
  1252  // This is useful if you're running in a Google AppEngine environment
  1253  // where the http.DefaultClient is not available.
  1254  func SetHTTPClient(client *http.Client) {
  1255  	httpClient = client
  1256  }
  1257  
  1258  // String returns a pointer to the string value passed in.
  1259  func String(v string) *string {
  1260  	return &v
  1261  }
  1262  
  1263  // StringValue returns the value of the string pointer passed in or
  1264  // "" if the pointer is nil.
  1265  func StringValue(v *string) string {
  1266  	if v != nil {
  1267  		return *v
  1268  	}
  1269  	return ""
  1270  }
  1271  
  1272  // StringSlice returns a slice of string pointers given a slice of strings.
  1273  func StringSlice(v []string) []*string {
  1274  	out := make([]*string, len(v))
  1275  	for i := range v {
  1276  		out[i] = &v[i]
  1277  	}
  1278  	return out
  1279  }
  1280  
  1281  //
  1282  // Private constants
  1283  //
  1284  
  1285  // clientversion is the binding version
  1286  const clientversion = "76.25.0"
  1287  
  1288  // defaultHTTPTimeout is the default timeout on the http.Client used by the library.
  1289  // This is chosen to be consistent with the other Stripe language libraries and
  1290  // to coordinate with other timeouts configured in the Stripe infrastructure.
  1291  const defaultHTTPTimeout = 80 * time.Second
  1292  
  1293  // maxNetworkRetriesDelay and minNetworkRetriesDelay defines sleep time in milliseconds between
  1294  // tries to send HTTP request again after network failure.
  1295  const maxNetworkRetriesDelay = 5000 * time.Millisecond
  1296  const minNetworkRetriesDelay = 500 * time.Millisecond
  1297  
  1298  // The number of requestMetric objects to buffer for client telemetry. When the
  1299  // buffer is full, new requestMetrics are dropped.
  1300  const telemetryBufferSize = 16
  1301  
  1302  //
  1303  // Private types
  1304  //
  1305  
  1306  // nopReadCloser's sole purpose is to give us a way to turn an `io.Reader` into
  1307  // an `io.ReadCloser` by adding a no-op implementation of the `Closer`
  1308  // interface. We need this because `http.Request`'s `Body` takes an
  1309  // `io.ReadCloser` instead of a `io.Reader`.
  1310  type nopReadCloser struct {
  1311  	io.Reader
  1312  }
  1313  
  1314  func (nopReadCloser) Close() error { return nil }
  1315  
  1316  // stripeClientUserAgent contains information about the current runtime which
  1317  // is serialized and sent in the `X-Stripe-Client-User-Agent` as additional
  1318  // debugging information.
  1319  type stripeClientUserAgent struct {
  1320  	Application     *AppInfo `json:"application"`
  1321  	BindingsVersion string   `json:"bindings_version"`
  1322  	Language        string   `json:"lang"`
  1323  	LanguageVersion string   `json:"lang_version"`
  1324  	Publisher       string   `json:"publisher"`
  1325  	Uname           string   `json:"uname"`
  1326  }
  1327  
  1328  // requestMetrics contains the id and duration of the last request sent
  1329  type requestMetrics struct {
  1330  	RequestDurationMS *int     `json:"request_duration_ms"`
  1331  	RequestID         string   `json:"request_id"`
  1332  	Usage             []string `json:"usage"`
  1333  }
  1334  
  1335  // requestTelemetry contains the payload sent in the
  1336  // `X-Stripe-Client-Telemetry` header when BackendConfig.EnableTelemetry = true.
  1337  type requestTelemetry struct {
  1338  	LastRequestMetrics requestMetrics `json:"last_request_metrics"`
  1339  }
  1340  
  1341  //
  1342  // Private variables
  1343  //
  1344  
  1345  var appInfo *AppInfo
  1346  var backends Backends
  1347  var encodedStripeUserAgent string
  1348  var encodedStripeUserAgentReady *sync.Once
  1349  var encodedUserAgent string
  1350  
  1351  // The default HTTP client used for communication with any of Stripe's
  1352  // backends.
  1353  //
  1354  // Can be overridden with the function `SetHTTPClient` or by setting the
  1355  // `HTTPClient` value when using `BackendConfig`.
  1356  //
  1357  // When adding something new here, see also `stripe_go115.go` where you'll want
  1358  // to add it as well.
  1359  var httpClient = &http.Client{
  1360  	Timeout: defaultHTTPTimeout,
  1361  
  1362  	// There is a bug in Go's HTTP/2 implementation that occasionally causes it
  1363  	// to send an empty body when it receives a `GOAWAY` message from a server:
  1364  	//
  1365  	//     https://github.com/golang/go/issues/32441
  1366  	//
  1367  	// This is particularly problematic for this library because the empty body
  1368  	// results in no parameters being sent, which usually results in a 400,
  1369  	// which is a status code expressly not covered by retry logic.
  1370  	//
  1371  	// The bug seems to be somewhat tricky to fix and hasn't seen any traction
  1372  	// lately, so for now we're mitigating by disabling HTTP/2 in stripe-go by
  1373  	// default. Users who like to live dangerously can still re-enable it by
  1374  	// specifying a custom HTTP client. When the bug above is fixed, we can
  1375  	// turn it back on.
  1376  	//
  1377  	// The particular methodology here for disabling HTTP/2 is a little
  1378  	// confusing at first glance, but is recommended by the `net/http`
  1379  	// documentation ("Programs that must disable HTTP/2 can do so by setting
  1380  	// Transport.TLSNextProto (for clients) ... to a non-nil, empty map.")
  1381  	//
  1382  	// Note that the test suite still uses HTTP/2 to run as it specifies its
  1383  	// own HTTP client with it enabled. See `testing/testing.go`.
  1384  	//
  1385  	// (Written 2019/07/24.)
  1386  	//
  1387  	// UPDATE: With the release of Go 1.15, this bug has been fixed.
  1388  	// As such, `stripe_go115.go` contains conditionally-compiled code that sets
  1389  	// a different HTTP client as the default, since Go 1.15+ does not contain
  1390  	// the aforementioned HTTP/2 bug.
  1391  	Transport: &http.Transport{
  1392  		TLSNextProto: make(map[string]func(string, *tls.Conn) http.RoundTripper),
  1393  	},
  1394  }
  1395  
  1396  //
  1397  // Private functions
  1398  //
  1399  
  1400  // getUname tries to get a uname from the system, but not that hard. It tries
  1401  // to execute `uname -a`, but swallows any errors in case that didn't work
  1402  // (i.e. non-Unix non-Mac system or some other reason).
  1403  func getUname() string {
  1404  	path, err := exec.LookPath("uname")
  1405  	if err != nil {
  1406  		return UnknownPlatform
  1407  	}
  1408  
  1409  	cmd := exec.Command(path, "-a")
  1410  	var out bytes.Buffer
  1411  	cmd.Stderr = nil // goes to os.DevNull
  1412  	cmd.Stdout = &out
  1413  	err = cmd.Run()
  1414  	if err != nil {
  1415  		return UnknownPlatform
  1416  	}
  1417  
  1418  	return out.String()
  1419  }
  1420  
  1421  func init() {
  1422  	initUserAgent()
  1423  }
  1424  
  1425  func initUserAgent() {
  1426  	encodedUserAgent = "Stripe/v1 GoBindings/" + clientversion
  1427  	if appInfo != nil {
  1428  		encodedUserAgent += " " + appInfo.formatUserAgent()
  1429  	}
  1430  	encodedStripeUserAgentReady = &sync.Once{}
  1431  }
  1432  
  1433  func getEncodedStripeUserAgent() string {
  1434  	encodedStripeUserAgentReady.Do(func() {
  1435  		stripeUserAgent := &stripeClientUserAgent{
  1436  			Application:     appInfo,
  1437  			BindingsVersion: clientversion,
  1438  			Language:        "go",
  1439  			LanguageVersion: runtime.Version(),
  1440  			Publisher:       "stripe",
  1441  			Uname:           getUname(),
  1442  		}
  1443  		marshaled, err := json.Marshal(stripeUserAgent)
  1444  		// Encoding this struct should never be a problem, so we're okay to panic
  1445  		// in case it is for some reason.
  1446  		if err != nil {
  1447  			panic(err)
  1448  		}
  1449  		encodedStripeUserAgent = string(marshaled)
  1450  	})
  1451  	return encodedStripeUserAgent
  1452  }
  1453  
  1454  func isHTTPWriteMethod(method string) bool {
  1455  	return method == http.MethodPost || method == http.MethodPut || method == http.MethodPatch || method == http.MethodDelete
  1456  }
  1457  
  1458  // newBackendImplementation returns a new Backend based off a given type and
  1459  // fully initialized BackendConfig struct.
  1460  //
  1461  // The vast majority of the time you should be calling GetBackendWithConfig
  1462  // instead of this function.
  1463  func newBackendImplementation(backendType SupportedBackend, config *BackendConfig) Backend {
  1464  	enableTelemetry := EnableTelemetry
  1465  	if config.EnableTelemetry != nil {
  1466  		enableTelemetry = *config.EnableTelemetry
  1467  	}
  1468  
  1469  	var requestMetricsBuffer chan requestMetrics
  1470  
  1471  	// only allocate the requestMetrics buffer if client telemetry is enabled.
  1472  	if enableTelemetry {
  1473  		requestMetricsBuffer = make(chan requestMetrics, telemetryBufferSize)
  1474  	}
  1475  
  1476  	return &BackendImplementation{
  1477  		HTTPClient:           config.HTTPClient,
  1478  		LeveledLogger:        config.LeveledLogger,
  1479  		MaxNetworkRetries:    *config.MaxNetworkRetries,
  1480  		Type:                 backendType,
  1481  		URL:                  *config.URL,
  1482  		enableTelemetry:      enableTelemetry,
  1483  		networkRetriesSleep:  true,
  1484  		requestMetricsBuffer: requestMetricsBuffer,
  1485  	}
  1486  }
  1487  
  1488  func normalizeURL(url string) string {
  1489  	// All paths include a leading slash, so to keep logs pretty, trim a
  1490  	// trailing slash on the URL.
  1491  	url = strings.TrimSuffix(url, "/")
  1492  
  1493  	// For a long time we had the `/v1` suffix as part of a configured URL
  1494  	// rather than in the per-package URLs throughout the library. Continue
  1495  	// to support this for the time being by stripping one that's been
  1496  	// passed for better backwards compatibility.
  1497  	url = strings.TrimSuffix(url, "/v1")
  1498  
  1499  	return url
  1500  }