mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	vendor oauth2@96382aa0 and add its deps
Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
This commit is contained in:
		
							parent
							
								
									a59625d912
								
							
						
					
					
						commit
						44b95265df
					
				
					 22 changed files with 1651 additions and 125 deletions
				
			
		| 
						 | 
				
			
			@ -88,9 +88,12 @@ github.com/jmespath/go-jmespath 0b12d6b521d83fc7f755e7cfc1b1fbdd35a01a74
 | 
			
		|||
github.com/bsphere/le_go d3308aafe090956bc89a65f0769f58251a1b4f03
 | 
			
		||||
 | 
			
		||||
# gcplogs deps
 | 
			
		||||
golang.org/x/oauth2 2baa8a1b9338cf13d9eeb27696d761155fa480be
 | 
			
		||||
golang.org/x/oauth2 96382aa079b72d8c014eb0c50f6c223d1e6a2de0
 | 
			
		||||
google.golang.org/api dc6d2353af16e2a2b0ff6986af051d473a4ed468
 | 
			
		||||
# TODO: remove google.golang.org/cloud, which has been replaced by cloud.google.com/go
 | 
			
		||||
google.golang.org/cloud dae7e3d993bc3812a2185af60552bb6b847e52a0
 | 
			
		||||
cloud.google.com/go 9d965e63e8cceb1b5d7977a202f0fcb8866d6525
 | 
			
		||||
github.com/googleapis/gax-go da06d194a00e19ce00d9011a13931c3f6f6887c7
 | 
			
		||||
 | 
			
		||||
# native credentials
 | 
			
		||||
github.com/docker/docker-credential-helpers f72c04f1d8e71959a6d103f808c50ccbad79b9fd
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										202
									
								
								vendor/cloud.google.com/go/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								vendor/cloud.google.com/go/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,202 @@
 | 
			
		|||
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
   APPENDIX: How to apply the Apache License to your work.
 | 
			
		||||
 | 
			
		||||
      To apply the Apache License to your work, attach the following
 | 
			
		||||
      boilerplate notice, with the fields enclosed by brackets "[]"
 | 
			
		||||
      replaced with your own identifying information. (Don't include
 | 
			
		||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
			
		||||
      comment syntax for the file format. We also recommend that a
 | 
			
		||||
      file or class name and description of purpose be included on the
 | 
			
		||||
      same "printed page" as the copyright notice for easier
 | 
			
		||||
      identification within third-party archives.
 | 
			
		||||
 | 
			
		||||
   Copyright 2014 Google Inc.
 | 
			
		||||
 | 
			
		||||
   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.
 | 
			
		||||
							
								
								
									
										438
									
								
								vendor/cloud.google.com/go/compute/metadata/metadata.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										438
									
								
								vendor/cloud.google.com/go/compute/metadata/metadata.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,438 @@
 | 
			
		|||
// Copyright 2014 Google Inc. All Rights Reserved.
 | 
			
		||||
//
 | 
			
		||||
// 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 metadata provides access to Google Compute Engine (GCE)
 | 
			
		||||
// metadata and API service accounts.
 | 
			
		||||
//
 | 
			
		||||
// This package is a wrapper around the GCE metadata service,
 | 
			
		||||
// as documented at https://developers.google.com/compute/docs/metadata.
 | 
			
		||||
package metadata // import "cloud.google.com/go/compute/metadata"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"net"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"os"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/net/context"
 | 
			
		||||
	"golang.org/x/net/context/ctxhttp"
 | 
			
		||||
 | 
			
		||||
	"cloud.google.com/go/internal"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// metadataIP is the documented metadata server IP address.
 | 
			
		||||
	metadataIP = "169.254.169.254"
 | 
			
		||||
 | 
			
		||||
	// metadataHostEnv is the environment variable specifying the
 | 
			
		||||
	// GCE metadata hostname.  If empty, the default value of
 | 
			
		||||
	// metadataIP ("169.254.169.254") is used instead.
 | 
			
		||||
	// This is variable name is not defined by any spec, as far as
 | 
			
		||||
	// I know; it was made up for the Go package.
 | 
			
		||||
	metadataHostEnv = "GCE_METADATA_HOST"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type cachedValue struct {
 | 
			
		||||
	k    string
 | 
			
		||||
	trim bool
 | 
			
		||||
	mu   sync.Mutex
 | 
			
		||||
	v    string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	projID  = &cachedValue{k: "project/project-id", trim: true}
 | 
			
		||||
	projNum = &cachedValue{k: "project/numeric-project-id", trim: true}
 | 
			
		||||
	instID  = &cachedValue{k: "instance/id", trim: true}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	metaClient = &http.Client{
 | 
			
		||||
		Transport: &internal.Transport{
 | 
			
		||||
			Base: &http.Transport{
 | 
			
		||||
				Dial: (&net.Dialer{
 | 
			
		||||
					Timeout:   2 * time.Second,
 | 
			
		||||
					KeepAlive: 30 * time.Second,
 | 
			
		||||
				}).Dial,
 | 
			
		||||
				ResponseHeaderTimeout: 2 * time.Second,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	subscribeClient = &http.Client{
 | 
			
		||||
		Transport: &internal.Transport{
 | 
			
		||||
			Base: &http.Transport{
 | 
			
		||||
				Dial: (&net.Dialer{
 | 
			
		||||
					Timeout:   2 * time.Second,
 | 
			
		||||
					KeepAlive: 30 * time.Second,
 | 
			
		||||
				}).Dial,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// NotDefinedError is returned when requested metadata is not defined.
 | 
			
		||||
//
 | 
			
		||||
// The underlying string is the suffix after "/computeMetadata/v1/".
 | 
			
		||||
//
 | 
			
		||||
// This error is not returned if the value is defined to be the empty
 | 
			
		||||
// string.
 | 
			
		||||
type NotDefinedError string
 | 
			
		||||
 | 
			
		||||
func (suffix NotDefinedError) Error() string {
 | 
			
		||||
	return fmt.Sprintf("metadata: GCE metadata %q not defined", string(suffix))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get returns a value from the metadata service.
 | 
			
		||||
// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/".
 | 
			
		||||
//
 | 
			
		||||
// If the GCE_METADATA_HOST environment variable is not defined, a default of
 | 
			
		||||
// 169.254.169.254 will be used instead.
 | 
			
		||||
//
 | 
			
		||||
// If the requested metadata is not defined, the returned error will
 | 
			
		||||
// be of type NotDefinedError.
 | 
			
		||||
func Get(suffix string) (string, error) {
 | 
			
		||||
	val, _, err := getETag(metaClient, suffix)
 | 
			
		||||
	return val, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getETag returns a value from the metadata service as well as the associated
 | 
			
		||||
// ETag using the provided client. This func is otherwise equivalent to Get.
 | 
			
		||||
func getETag(client *http.Client, suffix string) (value, etag string, err error) {
 | 
			
		||||
	// Using a fixed IP makes it very difficult to spoof the metadata service in
 | 
			
		||||
	// a container, which is an important use-case for local testing of cloud
 | 
			
		||||
	// deployments. To enable spoofing of the metadata service, the environment
 | 
			
		||||
	// variable GCE_METADATA_HOST is first inspected to decide where metadata
 | 
			
		||||
	// requests shall go.
 | 
			
		||||
	host := os.Getenv(metadataHostEnv)
 | 
			
		||||
	if host == "" {
 | 
			
		||||
		// Using 169.254.169.254 instead of "metadata" here because Go
 | 
			
		||||
		// binaries built with the "netgo" tag and without cgo won't
 | 
			
		||||
		// know the search suffix for "metadata" is
 | 
			
		||||
		// ".google.internal", and this IP address is documented as
 | 
			
		||||
		// being stable anyway.
 | 
			
		||||
		host = metadataIP
 | 
			
		||||
	}
 | 
			
		||||
	url := "http://" + host + "/computeMetadata/v1/" + suffix
 | 
			
		||||
	req, _ := http.NewRequest("GET", url, nil)
 | 
			
		||||
	req.Header.Set("Metadata-Flavor", "Google")
 | 
			
		||||
	res, err := client.Do(req)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", "", err
 | 
			
		||||
	}
 | 
			
		||||
	defer res.Body.Close()
 | 
			
		||||
	if res.StatusCode == http.StatusNotFound {
 | 
			
		||||
		return "", "", NotDefinedError(suffix)
 | 
			
		||||
	}
 | 
			
		||||
	if res.StatusCode != 200 {
 | 
			
		||||
		return "", "", fmt.Errorf("status code %d trying to fetch %s", res.StatusCode, url)
 | 
			
		||||
	}
 | 
			
		||||
	all, err := ioutil.ReadAll(res.Body)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", "", err
 | 
			
		||||
	}
 | 
			
		||||
	return string(all), res.Header.Get("Etag"), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getTrimmed(suffix string) (s string, err error) {
 | 
			
		||||
	s, err = Get(suffix)
 | 
			
		||||
	s = strings.TrimSpace(s)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *cachedValue) get() (v string, err error) {
 | 
			
		||||
	defer c.mu.Unlock()
 | 
			
		||||
	c.mu.Lock()
 | 
			
		||||
	if c.v != "" {
 | 
			
		||||
		return c.v, nil
 | 
			
		||||
	}
 | 
			
		||||
	if c.trim {
 | 
			
		||||
		v, err = getTrimmed(c.k)
 | 
			
		||||
	} else {
 | 
			
		||||
		v, err = Get(c.k)
 | 
			
		||||
	}
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		c.v = v
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	onGCEOnce sync.Once
 | 
			
		||||
	onGCE     bool
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// OnGCE reports whether this process is running on Google Compute Engine.
 | 
			
		||||
func OnGCE() bool {
 | 
			
		||||
	onGCEOnce.Do(initOnGCE)
 | 
			
		||||
	return onGCE
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func initOnGCE() {
 | 
			
		||||
	onGCE = testOnGCE()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func testOnGCE() bool {
 | 
			
		||||
	// The user explicitly said they're on GCE, so trust them.
 | 
			
		||||
	if os.Getenv(metadataHostEnv) != "" {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ctx, cancel := context.WithCancel(context.Background())
 | 
			
		||||
	defer cancel()
 | 
			
		||||
 | 
			
		||||
	resc := make(chan bool, 2)
 | 
			
		||||
 | 
			
		||||
	// Try two strategies in parallel.
 | 
			
		||||
	// See https://github.com/GoogleCloudPlatform/google-cloud-go/issues/194
 | 
			
		||||
	go func() {
 | 
			
		||||
		res, err := ctxhttp.Get(ctx, metaClient, "http://"+metadataIP)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			resc <- false
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		defer res.Body.Close()
 | 
			
		||||
		resc <- res.Header.Get("Metadata-Flavor") == "Google"
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	go func() {
 | 
			
		||||
		addrs, err := net.LookupHost("metadata.google.internal")
 | 
			
		||||
		if err != nil || len(addrs) == 0 {
 | 
			
		||||
			resc <- false
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		resc <- strsContains(addrs, metadataIP)
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	tryHarder := systemInfoSuggestsGCE()
 | 
			
		||||
	if tryHarder {
 | 
			
		||||
		res := <-resc
 | 
			
		||||
		if res {
 | 
			
		||||
			// The first strategy succeeded, so let's use it.
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
		// Wait for either the DNS or metadata server probe to
 | 
			
		||||
		// contradict the other one and say we are running on
 | 
			
		||||
		// GCE. Give it a lot of time to do so, since the system
 | 
			
		||||
		// info already suggests we're running on a GCE BIOS.
 | 
			
		||||
		timer := time.NewTimer(5 * time.Second)
 | 
			
		||||
		defer timer.Stop()
 | 
			
		||||
		select {
 | 
			
		||||
		case res = <-resc:
 | 
			
		||||
			return res
 | 
			
		||||
		case <-timer.C:
 | 
			
		||||
			// Too slow. Who knows what this system is.
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// There's no hint from the system info that we're running on
 | 
			
		||||
	// GCE, so use the first probe's result as truth, whether it's
 | 
			
		||||
	// true or false. The goal here is to optimize for speed for
 | 
			
		||||
	// users who are NOT running on GCE. We can't assume that
 | 
			
		||||
	// either a DNS lookup or an HTTP request to a blackholed IP
 | 
			
		||||
	// address is fast. Worst case this should return when the
 | 
			
		||||
	// metaClient's Transport.ResponseHeaderTimeout or
 | 
			
		||||
	// Transport.Dial.Timeout fires (in two seconds).
 | 
			
		||||
	return <-resc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// systemInfoSuggestsGCE reports whether the local system (without
 | 
			
		||||
// doing network requests) suggests that we're running on GCE. If this
 | 
			
		||||
// returns true, testOnGCE tries a bit harder to reach its metadata
 | 
			
		||||
// server.
 | 
			
		||||
func systemInfoSuggestsGCE() bool {
 | 
			
		||||
	if runtime.GOOS != "linux" {
 | 
			
		||||
		// We don't have any non-Linux clues available, at least yet.
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	slurp, _ := ioutil.ReadFile("/sys/class/dmi/id/product_name")
 | 
			
		||||
	name := strings.TrimSpace(string(slurp))
 | 
			
		||||
	return name == "Google" || name == "Google Compute Engine"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Subscribe subscribes to a value from the metadata service.
 | 
			
		||||
// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/".
 | 
			
		||||
// The suffix may contain query parameters.
 | 
			
		||||
//
 | 
			
		||||
// Subscribe calls fn with the latest metadata value indicated by the provided
 | 
			
		||||
// suffix. If the metadata value is deleted, fn is called with the empty string
 | 
			
		||||
// and ok false. Subscribe blocks until fn returns a non-nil error or the value
 | 
			
		||||
// is deleted. Subscribe returns the error value returned from the last call to
 | 
			
		||||
// fn, which may be nil when ok == false.
 | 
			
		||||
func Subscribe(suffix string, fn func(v string, ok bool) error) error {
 | 
			
		||||
	const failedSubscribeSleep = time.Second * 5
 | 
			
		||||
 | 
			
		||||
	// First check to see if the metadata value exists at all.
 | 
			
		||||
	val, lastETag, err := getETag(subscribeClient, suffix)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := fn(val, true); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ok := true
 | 
			
		||||
	if strings.ContainsRune(suffix, '?') {
 | 
			
		||||
		suffix += "&wait_for_change=true&last_etag="
 | 
			
		||||
	} else {
 | 
			
		||||
		suffix += "?wait_for_change=true&last_etag="
 | 
			
		||||
	}
 | 
			
		||||
	for {
 | 
			
		||||
		val, etag, err := getETag(subscribeClient, suffix+url.QueryEscape(lastETag))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if _, deleted := err.(NotDefinedError); !deleted {
 | 
			
		||||
				time.Sleep(failedSubscribeSleep)
 | 
			
		||||
				continue // Retry on other errors.
 | 
			
		||||
			}
 | 
			
		||||
			ok = false
 | 
			
		||||
		}
 | 
			
		||||
		lastETag = etag
 | 
			
		||||
 | 
			
		||||
		if err := fn(val, ok); err != nil || !ok {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ProjectID returns the current instance's project ID string.
 | 
			
		||||
func ProjectID() (string, error) { return projID.get() }
 | 
			
		||||
 | 
			
		||||
// NumericProjectID returns the current instance's numeric project ID.
 | 
			
		||||
func NumericProjectID() (string, error) { return projNum.get() }
 | 
			
		||||
 | 
			
		||||
// InternalIP returns the instance's primary internal IP address.
 | 
			
		||||
func InternalIP() (string, error) {
 | 
			
		||||
	return getTrimmed("instance/network-interfaces/0/ip")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ExternalIP returns the instance's primary external (public) IP address.
 | 
			
		||||
func ExternalIP() (string, error) {
 | 
			
		||||
	return getTrimmed("instance/network-interfaces/0/access-configs/0/external-ip")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Hostname returns the instance's hostname. This will be of the form
 | 
			
		||||
// "<instanceID>.c.<projID>.internal".
 | 
			
		||||
func Hostname() (string, error) {
 | 
			
		||||
	return getTrimmed("instance/hostname")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstanceTags returns the list of user-defined instance tags,
 | 
			
		||||
// assigned when initially creating a GCE instance.
 | 
			
		||||
func InstanceTags() ([]string, error) {
 | 
			
		||||
	var s []string
 | 
			
		||||
	j, err := Get("instance/tags")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if err := json.NewDecoder(strings.NewReader(j)).Decode(&s); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return s, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstanceID returns the current VM's numeric instance ID.
 | 
			
		||||
func InstanceID() (string, error) {
 | 
			
		||||
	return instID.get()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstanceName returns the current VM's instance ID string.
 | 
			
		||||
func InstanceName() (string, error) {
 | 
			
		||||
	host, err := Hostname()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	return strings.Split(host, ".")[0], nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Zone returns the current VM's zone, such as "us-central1-b".
 | 
			
		||||
func Zone() (string, error) {
 | 
			
		||||
	zone, err := getTrimmed("instance/zone")
 | 
			
		||||
	// zone is of the form "projects/<projNum>/zones/<zoneName>".
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	return zone[strings.LastIndex(zone, "/")+1:], nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstanceAttributes returns the list of user-defined attributes,
 | 
			
		||||
// assigned when initially creating a GCE VM instance. The value of an
 | 
			
		||||
// attribute can be obtained with InstanceAttributeValue.
 | 
			
		||||
func InstanceAttributes() ([]string, error) { return lines("instance/attributes/") }
 | 
			
		||||
 | 
			
		||||
// ProjectAttributes returns the list of user-defined attributes
 | 
			
		||||
// applying to the project as a whole, not just this VM.  The value of
 | 
			
		||||
// an attribute can be obtained with ProjectAttributeValue.
 | 
			
		||||
func ProjectAttributes() ([]string, error) { return lines("project/attributes/") }
 | 
			
		||||
 | 
			
		||||
func lines(suffix string) ([]string, error) {
 | 
			
		||||
	j, err := Get(suffix)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	s := strings.Split(strings.TrimSpace(j), "\n")
 | 
			
		||||
	for i := range s {
 | 
			
		||||
		s[i] = strings.TrimSpace(s[i])
 | 
			
		||||
	}
 | 
			
		||||
	return s, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstanceAttributeValue returns the value of the provided VM
 | 
			
		||||
// instance attribute.
 | 
			
		||||
//
 | 
			
		||||
// If the requested attribute is not defined, the returned error will
 | 
			
		||||
// be of type NotDefinedError.
 | 
			
		||||
//
 | 
			
		||||
// InstanceAttributeValue may return ("", nil) if the attribute was
 | 
			
		||||
// defined to be the empty string.
 | 
			
		||||
func InstanceAttributeValue(attr string) (string, error) {
 | 
			
		||||
	return Get("instance/attributes/" + attr)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ProjectAttributeValue returns the value of the provided
 | 
			
		||||
// project attribute.
 | 
			
		||||
//
 | 
			
		||||
// If the requested attribute is not defined, the returned error will
 | 
			
		||||
// be of type NotDefinedError.
 | 
			
		||||
//
 | 
			
		||||
// ProjectAttributeValue may return ("", nil) if the attribute was
 | 
			
		||||
// defined to be the empty string.
 | 
			
		||||
func ProjectAttributeValue(attr string) (string, error) {
 | 
			
		||||
	return Get("project/attributes/" + attr)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Scopes returns the service account scopes for the given account.
 | 
			
		||||
// The account may be empty or the string "default" to use the instance's
 | 
			
		||||
// main account.
 | 
			
		||||
func Scopes(serviceAccount string) ([]string, error) {
 | 
			
		||||
	if serviceAccount == "" {
 | 
			
		||||
		serviceAccount = "default"
 | 
			
		||||
	}
 | 
			
		||||
	return lines("instance/service-accounts/" + serviceAccount + "/scopes")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func strsContains(ss []string, s string) bool {
 | 
			
		||||
	for _, v := range ss {
 | 
			
		||||
		if v == s {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										64
									
								
								vendor/cloud.google.com/go/internal/cloud.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								vendor/cloud.google.com/go/internal/cloud.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,64 @@
 | 
			
		|||
// Copyright 2014 Google Inc. All Rights Reserved.
 | 
			
		||||
//
 | 
			
		||||
// 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 internal provides support for the cloud packages.
 | 
			
		||||
//
 | 
			
		||||
// Users should not import this package directly.
 | 
			
		||||
package internal
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const userAgent = "gcloud-golang/0.1"
 | 
			
		||||
 | 
			
		||||
// Transport is an http.RoundTripper that appends Google Cloud client's
 | 
			
		||||
// user-agent to the original request's user-agent header.
 | 
			
		||||
type Transport struct {
 | 
			
		||||
	// TODO(bradfitz): delete internal.Transport. It's too wrappy for what it does.
 | 
			
		||||
	// Do User-Agent some other way.
 | 
			
		||||
 | 
			
		||||
	// Base is the actual http.RoundTripper
 | 
			
		||||
	// requests will use. It must not be nil.
 | 
			
		||||
	Base http.RoundTripper
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RoundTrip appends a user-agent to the existing user-agent
 | 
			
		||||
// header and delegates the request to the base http.RoundTripper.
 | 
			
		||||
func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
 | 
			
		||||
	req = cloneRequest(req)
 | 
			
		||||
	ua := req.Header.Get("User-Agent")
 | 
			
		||||
	if ua == "" {
 | 
			
		||||
		ua = userAgent
 | 
			
		||||
	} else {
 | 
			
		||||
		ua = fmt.Sprintf("%s %s", ua, userAgent)
 | 
			
		||||
	}
 | 
			
		||||
	req.Header.Set("User-Agent", ua)
 | 
			
		||||
	return t.Base.RoundTrip(req)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// cloneRequest returns a clone of the provided *http.Request.
 | 
			
		||||
// The clone is a shallow copy of the struct and its Header map.
 | 
			
		||||
func cloneRequest(r *http.Request) *http.Request {
 | 
			
		||||
	// shallow copy of the struct
 | 
			
		||||
	r2 := new(http.Request)
 | 
			
		||||
	*r2 = *r
 | 
			
		||||
	// deep copy of the Header
 | 
			
		||||
	r2.Header = make(http.Header)
 | 
			
		||||
	for k, s := range r.Header {
 | 
			
		||||
		r2.Header[k] = s
 | 
			
		||||
	}
 | 
			
		||||
	return r2
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								vendor/cloud.google.com/go/internal/retry.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								vendor/cloud.google.com/go/internal/retry.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,55 @@
 | 
			
		|||
// Copyright 2016 Google Inc. All Rights Reserved.
 | 
			
		||||
//
 | 
			
		||||
// 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 internal
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	gax "github.com/googleapis/gax-go"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/net/context"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Retry calls the supplied function f repeatedly according to the provided
 | 
			
		||||
// backoff parameters. It returns when one of the following occurs:
 | 
			
		||||
// When f's first return value is true, Retry immediately returns with f's second
 | 
			
		||||
// return value.
 | 
			
		||||
// When the provided context is done, Retry returns with ctx.Err().
 | 
			
		||||
func Retry(ctx context.Context, bo gax.Backoff, f func() (stop bool, err error)) error {
 | 
			
		||||
	return retry(ctx, bo, f, gax.Sleep)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func retry(ctx context.Context, bo gax.Backoff, f func() (stop bool, err error),
 | 
			
		||||
	sleep func(context.Context, time.Duration) error) error {
 | 
			
		||||
	var lastErr error
 | 
			
		||||
	for {
 | 
			
		||||
		stop, err := f()
 | 
			
		||||
		if stop {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		// Remember the last "real" error from f.
 | 
			
		||||
		if err != nil && err != context.Canceled && err != context.DeadlineExceeded {
 | 
			
		||||
			lastErr = err
 | 
			
		||||
		}
 | 
			
		||||
		p := bo.Pause()
 | 
			
		||||
		if cerr := sleep(ctx, p); cerr != nil {
 | 
			
		||||
			if lastErr != nil {
 | 
			
		||||
				return fmt.Errorf("%v; last function err: %v", cerr, lastErr)
 | 
			
		||||
			}
 | 
			
		||||
			return cerr
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								vendor/github.com/googleapis/gax-go/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/googleapis/gax-go/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
Copyright 2016, Google Inc.
 | 
			
		||||
All rights reserved.
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are
 | 
			
		||||
met:
 | 
			
		||||
 | 
			
		||||
   * Redistributions of source code must retain the above copyright
 | 
			
		||||
notice, this list of conditions and the following disclaimer.
 | 
			
		||||
   * Redistributions in binary form must reproduce the above
 | 
			
		||||
copyright notice, this list of conditions and the following disclaimer
 | 
			
		||||
in the documentation and/or other materials provided with the
 | 
			
		||||
distribution.
 | 
			
		||||
   * Neither the name of Google Inc. nor the names of its
 | 
			
		||||
contributors may be used to endorse or promote products derived from
 | 
			
		||||
this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
			
		||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
			
		||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
			
		||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
			
		||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
							
								
								
									
										136
									
								
								vendor/github.com/googleapis/gax-go/call_option.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								vendor/github.com/googleapis/gax-go/call_option.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,136 @@
 | 
			
		|||
// Copyright 2016, Google Inc.
 | 
			
		||||
// All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
// Redistribution and use in source and binary forms, with or without
 | 
			
		||||
// modification, are permitted provided that the following conditions are
 | 
			
		||||
// met:
 | 
			
		||||
//
 | 
			
		||||
//     * Redistributions of source code must retain the above copyright
 | 
			
		||||
// notice, this list of conditions and the following disclaimer.
 | 
			
		||||
//     * Redistributions in binary form must reproduce the above
 | 
			
		||||
// copyright notice, this list of conditions and the following disclaimer
 | 
			
		||||
// in the documentation and/or other materials provided with the
 | 
			
		||||
// distribution.
 | 
			
		||||
//     * Neither the name of Google Inc. nor the names of its
 | 
			
		||||
// contributors may be used to endorse or promote products derived from
 | 
			
		||||
// this software without specific prior written permission.
 | 
			
		||||
//
 | 
			
		||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
			
		||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
			
		||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
			
		||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
			
		||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
package gax
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"math/rand"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"google.golang.org/grpc"
 | 
			
		||||
	"google.golang.org/grpc/codes"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CallOption is an option used by Invoke to control behaviors of RPC calls.
 | 
			
		||||
// CallOption works by modifying relevant fields of CallSettings.
 | 
			
		||||
type CallOption interface {
 | 
			
		||||
	// Resolve applies the option by modifying cs.
 | 
			
		||||
	Resolve(cs *CallSettings)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Retryer is used by Invoke to determine retry behavior.
 | 
			
		||||
type Retryer interface {
 | 
			
		||||
	// Retry reports whether a request should be retriedand how long to pause before retrying
 | 
			
		||||
	// if the previous attempt returned with err. Invoke never calls Retry with nil error.
 | 
			
		||||
	Retry(err error) (pause time.Duration, shouldRetry bool)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type retryerOption func() Retryer
 | 
			
		||||
 | 
			
		||||
func (o retryerOption) Resolve(s *CallSettings) {
 | 
			
		||||
	s.Retry = o
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithRetry sets CallSettings.Retry to fn.
 | 
			
		||||
func WithRetry(fn func() Retryer) CallOption {
 | 
			
		||||
	return retryerOption(fn)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// OnCodes returns a Retryer that retries if and only if
 | 
			
		||||
// the previous attempt returns a GRPC error whose error code is stored in cc.
 | 
			
		||||
// Pause times between retries are specified by bo.
 | 
			
		||||
//
 | 
			
		||||
// bo is only used for its parameters; each Retryer has its own copy.
 | 
			
		||||
func OnCodes(cc []codes.Code, bo Backoff) Retryer {
 | 
			
		||||
	return &boRetryer{
 | 
			
		||||
		backoff: bo,
 | 
			
		||||
		codes:   append([]codes.Code(nil), cc...),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type boRetryer struct {
 | 
			
		||||
	backoff Backoff
 | 
			
		||||
	codes   []codes.Code
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *boRetryer) Retry(err error) (time.Duration, bool) {
 | 
			
		||||
	c := grpc.Code(err)
 | 
			
		||||
	for _, rc := range r.codes {
 | 
			
		||||
		if c == rc {
 | 
			
		||||
			return r.backoff.Pause(), true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return 0, false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Backoff implements exponential backoff.
 | 
			
		||||
// The wait time between retries is a random value between 0 and the "retry envelope".
 | 
			
		||||
// The envelope starts at Initial and increases by the factor of Multiplier every retry,
 | 
			
		||||
// but is capped at Max.
 | 
			
		||||
type Backoff struct {
 | 
			
		||||
	// Initial is the initial value of the retry envelope, defaults to 1 second.
 | 
			
		||||
	Initial time.Duration
 | 
			
		||||
 | 
			
		||||
	// Max is the maximum value of the retry envelope, defaults to 30 seconds.
 | 
			
		||||
	Max time.Duration
 | 
			
		||||
 | 
			
		||||
	// Multiplier is the factor by which the retry envelope increases.
 | 
			
		||||
	// It should be greater than 1 and defaults to 2.
 | 
			
		||||
	Multiplier float64
 | 
			
		||||
 | 
			
		||||
	// cur is the current retry envelope
 | 
			
		||||
	cur time.Duration
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bo *Backoff) Pause() time.Duration {
 | 
			
		||||
	if bo.Initial == 0 {
 | 
			
		||||
		bo.Initial = time.Second
 | 
			
		||||
	}
 | 
			
		||||
	if bo.cur == 0 {
 | 
			
		||||
		bo.cur = bo.Initial
 | 
			
		||||
	}
 | 
			
		||||
	if bo.Max == 0 {
 | 
			
		||||
		bo.Max = 30 * time.Second
 | 
			
		||||
	}
 | 
			
		||||
	if bo.Multiplier < 1 {
 | 
			
		||||
		bo.Multiplier = 2
 | 
			
		||||
	}
 | 
			
		||||
	d := time.Duration(rand.Int63n(int64(bo.cur)))
 | 
			
		||||
	bo.cur = time.Duration(float64(bo.cur) * bo.Multiplier)
 | 
			
		||||
	if bo.cur > bo.Max {
 | 
			
		||||
		bo.cur = bo.Max
 | 
			
		||||
	}
 | 
			
		||||
	return d
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CallSettings struct {
 | 
			
		||||
	// Retry returns a Retryer to be used to control retry logic of a method call.
 | 
			
		||||
	// If Retry is nil or the returned Retryer is nil, the call will not be retried.
 | 
			
		||||
	Retry func() Retryer
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								vendor/github.com/googleapis/gax-go/gax.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								vendor/github.com/googleapis/gax-go/gax.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,40 @@
 | 
			
		|||
// Copyright 2016, Google Inc.
 | 
			
		||||
// All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
// Redistribution and use in source and binary forms, with or without
 | 
			
		||||
// modification, are permitted provided that the following conditions are
 | 
			
		||||
// met:
 | 
			
		||||
//
 | 
			
		||||
//     * Redistributions of source code must retain the above copyright
 | 
			
		||||
// notice, this list of conditions and the following disclaimer.
 | 
			
		||||
//     * Redistributions in binary form must reproduce the above
 | 
			
		||||
// copyright notice, this list of conditions and the following disclaimer
 | 
			
		||||
// in the documentation and/or other materials provided with the
 | 
			
		||||
// distribution.
 | 
			
		||||
//     * Neither the name of Google Inc. nor the names of its
 | 
			
		||||
// contributors may be used to endorse or promote products derived from
 | 
			
		||||
// this software without specific prior written permission.
 | 
			
		||||
//
 | 
			
		||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
			
		||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
			
		||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
			
		||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
			
		||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
// Package gax contains a set of modules which aid the development of APIs
 | 
			
		||||
// for clients and servers based on gRPC and Google API conventions.
 | 
			
		||||
//
 | 
			
		||||
// Application code will rarely need to use this library directly.
 | 
			
		||||
// However, code generated automatically from API definition files can use it
 | 
			
		||||
// to simplify code generation and to provide more convenient and idiomatic API surfaces.
 | 
			
		||||
//
 | 
			
		||||
// This project is currently experimental and not supported.
 | 
			
		||||
package gax
 | 
			
		||||
 | 
			
		||||
const Version = "0.1.0"
 | 
			
		||||
							
								
								
									
										90
									
								
								vendor/github.com/googleapis/gax-go/invoke.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								vendor/github.com/googleapis/gax-go/invoke.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,90 @@
 | 
			
		|||
// Copyright 2016, Google Inc.
 | 
			
		||||
// All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
// Redistribution and use in source and binary forms, with or without
 | 
			
		||||
// modification, are permitted provided that the following conditions are
 | 
			
		||||
// met:
 | 
			
		||||
//
 | 
			
		||||
//     * Redistributions of source code must retain the above copyright
 | 
			
		||||
// notice, this list of conditions and the following disclaimer.
 | 
			
		||||
//     * Redistributions in binary form must reproduce the above
 | 
			
		||||
// copyright notice, this list of conditions and the following disclaimer
 | 
			
		||||
// in the documentation and/or other materials provided with the
 | 
			
		||||
// distribution.
 | 
			
		||||
//     * Neither the name of Google Inc. nor the names of its
 | 
			
		||||
// contributors may be used to endorse or promote products derived from
 | 
			
		||||
// this software without specific prior written permission.
 | 
			
		||||
//
 | 
			
		||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
			
		||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
			
		||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
			
		||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
			
		||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
package gax
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/net/context"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// A user defined call stub.
 | 
			
		||||
type APICall func(context.Context) error
 | 
			
		||||
 | 
			
		||||
// Invoke calls the given APICall,
 | 
			
		||||
// performing retries as specified by opts, if any.
 | 
			
		||||
func Invoke(ctx context.Context, call APICall, opts ...CallOption) error {
 | 
			
		||||
	var settings CallSettings
 | 
			
		||||
	for _, opt := range opts {
 | 
			
		||||
		opt.Resolve(&settings)
 | 
			
		||||
	}
 | 
			
		||||
	return invoke(ctx, call, settings, Sleep)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sleep is similar to time.Sleep, but it can be interrupted by ctx.Done() closing.
 | 
			
		||||
// If interrupted, Sleep returns ctx.Err().
 | 
			
		||||
func Sleep(ctx context.Context, d time.Duration) error {
 | 
			
		||||
	t := time.NewTimer(d)
 | 
			
		||||
	select {
 | 
			
		||||
	case <-ctx.Done():
 | 
			
		||||
		t.Stop()
 | 
			
		||||
		return ctx.Err()
 | 
			
		||||
	case <-t.C:
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type sleeper func(ctx context.Context, d time.Duration) error
 | 
			
		||||
 | 
			
		||||
// invoke implements Invoke, taking an additional sleeper argument for testing.
 | 
			
		||||
func invoke(ctx context.Context, call APICall, settings CallSettings, sp sleeper) error {
 | 
			
		||||
	var retryer Retryer
 | 
			
		||||
	for {
 | 
			
		||||
		err := call(ctx)
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
		if settings.Retry == nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		if retryer == nil {
 | 
			
		||||
			if r := settings.Retry(); r != nil {
 | 
			
		||||
				retryer = r
 | 
			
		||||
			} else {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if d, ok := retryer.Retry(err); !ok {
 | 
			
		||||
			return err
 | 
			
		||||
		} else if err = sp(ctx, d); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										176
									
								
								vendor/github.com/googleapis/gax-go/path_template.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								vendor/github.com/googleapis/gax-go/path_template.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,176 @@
 | 
			
		|||
// Copyright 2016, Google Inc.
 | 
			
		||||
// All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
// Redistribution and use in source and binary forms, with or without
 | 
			
		||||
// modification, are permitted provided that the following conditions are
 | 
			
		||||
// met:
 | 
			
		||||
//
 | 
			
		||||
//     * Redistributions of source code must retain the above copyright
 | 
			
		||||
// notice, this list of conditions and the following disclaimer.
 | 
			
		||||
//     * Redistributions in binary form must reproduce the above
 | 
			
		||||
// copyright notice, this list of conditions and the following disclaimer
 | 
			
		||||
// in the documentation and/or other materials provided with the
 | 
			
		||||
// distribution.
 | 
			
		||||
//     * Neither the name of Google Inc. nor the names of its
 | 
			
		||||
// contributors may be used to endorse or promote products derived from
 | 
			
		||||
// this software without specific prior written permission.
 | 
			
		||||
//
 | 
			
		||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
			
		||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
			
		||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
			
		||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
			
		||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
package gax
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type matcher interface {
 | 
			
		||||
	match([]string) (int, error)
 | 
			
		||||
	String() string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type segment struct {
 | 
			
		||||
	matcher
 | 
			
		||||
	name string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type labelMatcher string
 | 
			
		||||
 | 
			
		||||
func (ls labelMatcher) match(segments []string) (int, error) {
 | 
			
		||||
	if len(segments) == 0 {
 | 
			
		||||
		return 0, fmt.Errorf("expected %s but no more segments found", ls)
 | 
			
		||||
	}
 | 
			
		||||
	if segments[0] != string(ls) {
 | 
			
		||||
		return 0, fmt.Errorf("expected %s but got %s", ls, segments[0])
 | 
			
		||||
	}
 | 
			
		||||
	return 1, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ls labelMatcher) String() string {
 | 
			
		||||
	return string(ls)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type wildcardMatcher int
 | 
			
		||||
 | 
			
		||||
func (wm wildcardMatcher) match(segments []string) (int, error) {
 | 
			
		||||
	if len(segments) == 0 {
 | 
			
		||||
		return 0, errors.New("no more segments found")
 | 
			
		||||
	}
 | 
			
		||||
	return 1, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (wm wildcardMatcher) String() string {
 | 
			
		||||
	return "*"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type pathWildcardMatcher int
 | 
			
		||||
 | 
			
		||||
func (pwm pathWildcardMatcher) match(segments []string) (int, error) {
 | 
			
		||||
	length := len(segments) - int(pwm)
 | 
			
		||||
	if length <= 0 {
 | 
			
		||||
		return 0, errors.New("not sufficient segments are supplied for path wildcard")
 | 
			
		||||
	}
 | 
			
		||||
	return length, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (pwm pathWildcardMatcher) String() string {
 | 
			
		||||
	return "**"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ParseError struct {
 | 
			
		||||
	Pos      int
 | 
			
		||||
	Template string
 | 
			
		||||
	Message  string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (pe ParseError) Error() string {
 | 
			
		||||
	return fmt.Sprintf("at %d of template '%s', %s", pe.Pos, pe.Template, pe.Message)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PathTemplate manages the template to build and match with paths used
 | 
			
		||||
// by API services. It holds a template and variable names in it, and
 | 
			
		||||
// it can extract matched patterns from a path string or build a path
 | 
			
		||||
// string from a binding.
 | 
			
		||||
//
 | 
			
		||||
// See http.proto in github.com/googleapis/googleapis/ for the details of
 | 
			
		||||
// the template syntax.
 | 
			
		||||
type PathTemplate struct {
 | 
			
		||||
	segments []segment
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewPathTemplate parses a path template, and returns a PathTemplate
 | 
			
		||||
// instance if successful.
 | 
			
		||||
func NewPathTemplate(template string) (*PathTemplate, error) {
 | 
			
		||||
	return parsePathTemplate(template)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MustCompilePathTemplate is like NewPathTemplate but panics if the
 | 
			
		||||
// expression cannot be parsed. It simplifies safe initialization of
 | 
			
		||||
// global variables holding compiled regular expressions.
 | 
			
		||||
func MustCompilePathTemplate(template string) *PathTemplate {
 | 
			
		||||
	pt, err := NewPathTemplate(template)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
	return pt
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Match attempts to match the given path with the template, and returns
 | 
			
		||||
// the mapping of the variable name to the matched pattern string.
 | 
			
		||||
func (pt *PathTemplate) Match(path string) (map[string]string, error) {
 | 
			
		||||
	paths := strings.Split(path, "/")
 | 
			
		||||
	values := map[string]string{}
 | 
			
		||||
	for _, segment := range pt.segments {
 | 
			
		||||
		length, err := segment.match(paths)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		if segment.name != "" {
 | 
			
		||||
			value := strings.Join(paths[:length], "/")
 | 
			
		||||
			if oldValue, ok := values[segment.name]; ok {
 | 
			
		||||
				values[segment.name] = oldValue + "/" + value
 | 
			
		||||
			} else {
 | 
			
		||||
				values[segment.name] = value
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		paths = paths[length:]
 | 
			
		||||
	}
 | 
			
		||||
	if len(paths) != 0 {
 | 
			
		||||
		return nil, fmt.Errorf("Trailing path %s remains after the matching", strings.Join(paths, "/"))
 | 
			
		||||
	}
 | 
			
		||||
	return values, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Render creates a path string from its template and the binding from
 | 
			
		||||
// the variable name to the value.
 | 
			
		||||
func (pt *PathTemplate) Render(binding map[string]string) (string, error) {
 | 
			
		||||
	result := make([]string, 0, len(pt.segments))
 | 
			
		||||
	var lastVariableName string
 | 
			
		||||
	for _, segment := range pt.segments {
 | 
			
		||||
		name := segment.name
 | 
			
		||||
		if lastVariableName != "" && name == lastVariableName {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		lastVariableName = name
 | 
			
		||||
		if name == "" {
 | 
			
		||||
			result = append(result, segment.String())
 | 
			
		||||
		} else if value, ok := binding[name]; ok {
 | 
			
		||||
			result = append(result, value)
 | 
			
		||||
		} else {
 | 
			
		||||
			return "", fmt.Errorf("%s is not found", name)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	built := strings.Join(result, "/")
 | 
			
		||||
	return built, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										227
									
								
								vendor/github.com/googleapis/gax-go/path_template_parser.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										227
									
								
								vendor/github.com/googleapis/gax-go/path_template_parser.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,227 @@
 | 
			
		|||
// Copyright 2016, Google Inc.
 | 
			
		||||
// All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
// Redistribution and use in source and binary forms, with or without
 | 
			
		||||
// modification, are permitted provided that the following conditions are
 | 
			
		||||
// met:
 | 
			
		||||
//
 | 
			
		||||
//     * Redistributions of source code must retain the above copyright
 | 
			
		||||
// notice, this list of conditions and the following disclaimer.
 | 
			
		||||
//     * Redistributions in binary form must reproduce the above
 | 
			
		||||
// copyright notice, this list of conditions and the following disclaimer
 | 
			
		||||
// in the documentation and/or other materials provided with the
 | 
			
		||||
// distribution.
 | 
			
		||||
//     * Neither the name of Google Inc. nor the names of its
 | 
			
		||||
// contributors may be used to endorse or promote products derived from
 | 
			
		||||
// this software without specific prior written permission.
 | 
			
		||||
//
 | 
			
		||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
			
		||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
			
		||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
			
		||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
			
		||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
package gax
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// This parser follows the syntax of path templates, from
 | 
			
		||||
// https://github.com/googleapis/googleapis/blob/master/google/api/http.proto.
 | 
			
		||||
// The differences are that there is no custom verb, we allow the initial slash
 | 
			
		||||
// to be absent, and that we are not strict as
 | 
			
		||||
// https://tools.ietf.org/html/rfc6570 about the characters in identifiers and
 | 
			
		||||
// literals.
 | 
			
		||||
 | 
			
		||||
type pathTemplateParser struct {
 | 
			
		||||
	r                *strings.Reader
 | 
			
		||||
	runeCount        int             // the number of the current rune in the original string
 | 
			
		||||
	nextVar          int             // the number to use for the next unnamed variable
 | 
			
		||||
	seenName         map[string]bool // names we've seen already
 | 
			
		||||
	seenPathWildcard bool            // have we seen "**" already?
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func parsePathTemplate(template string) (pt *PathTemplate, err error) {
 | 
			
		||||
	p := &pathTemplateParser{
 | 
			
		||||
		r:        strings.NewReader(template),
 | 
			
		||||
		seenName: map[string]bool{},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Handle panics with strings like errors.
 | 
			
		||||
	// See pathTemplateParser.error, below.
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if x := recover(); x != nil {
 | 
			
		||||
			errmsg, ok := x.(errString)
 | 
			
		||||
			if !ok {
 | 
			
		||||
				panic(x)
 | 
			
		||||
			}
 | 
			
		||||
			pt = nil
 | 
			
		||||
			err = ParseError{p.runeCount, template, string(errmsg)}
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	segs := p.template()
 | 
			
		||||
	// If there is a path wildcard, set its length. We can't do this
 | 
			
		||||
	// until we know how many segments we've got all together.
 | 
			
		||||
	for i, seg := range segs {
 | 
			
		||||
		if _, ok := seg.matcher.(pathWildcardMatcher); ok {
 | 
			
		||||
			segs[i].matcher = pathWildcardMatcher(len(segs) - i - 1)
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return &PathTemplate{segments: segs}, nil
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Used to indicate errors "thrown" by this parser. We don't use string because
 | 
			
		||||
// many parts of the standard library panic with strings.
 | 
			
		||||
type errString string
 | 
			
		||||
 | 
			
		||||
// Terminates parsing immediately with an error.
 | 
			
		||||
func (p *pathTemplateParser) error(msg string) {
 | 
			
		||||
	panic(errString(msg))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Template = [ "/" ] Segments
 | 
			
		||||
func (p *pathTemplateParser) template() []segment {
 | 
			
		||||
	var segs []segment
 | 
			
		||||
	if p.consume('/') {
 | 
			
		||||
		// Initial '/' needs an initial empty matcher.
 | 
			
		||||
		segs = append(segs, segment{matcher: labelMatcher("")})
 | 
			
		||||
	}
 | 
			
		||||
	return append(segs, p.segments("")...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Segments = Segment { "/" Segment }
 | 
			
		||||
func (p *pathTemplateParser) segments(name string) []segment {
 | 
			
		||||
	var segs []segment
 | 
			
		||||
	for {
 | 
			
		||||
		subsegs := p.segment(name)
 | 
			
		||||
		segs = append(segs, subsegs...)
 | 
			
		||||
		if !p.consume('/') {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return segs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Segment  = "*" | "**" | LITERAL | Variable
 | 
			
		||||
func (p *pathTemplateParser) segment(name string) []segment {
 | 
			
		||||
	if p.consume('*') {
 | 
			
		||||
		if name == "" {
 | 
			
		||||
			name = fmt.Sprintf("$%d", p.nextVar)
 | 
			
		||||
			p.nextVar++
 | 
			
		||||
		}
 | 
			
		||||
		if p.consume('*') {
 | 
			
		||||
			if p.seenPathWildcard {
 | 
			
		||||
				p.error("multiple '**' disallowed")
 | 
			
		||||
			}
 | 
			
		||||
			p.seenPathWildcard = true
 | 
			
		||||
			// We'll change 0 to the right number at the end.
 | 
			
		||||
			return []segment{{name: name, matcher: pathWildcardMatcher(0)}}
 | 
			
		||||
		}
 | 
			
		||||
		return []segment{{name: name, matcher: wildcardMatcher(0)}}
 | 
			
		||||
	}
 | 
			
		||||
	if p.consume('{') {
 | 
			
		||||
		if name != "" {
 | 
			
		||||
			p.error("recursive named bindings are not allowed")
 | 
			
		||||
		}
 | 
			
		||||
		return p.variable()
 | 
			
		||||
	}
 | 
			
		||||
	return []segment{{name: name, matcher: labelMatcher(p.literal())}}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Variable = "{" FieldPath [ "=" Segments ] "}"
 | 
			
		||||
// "{" is already consumed.
 | 
			
		||||
func (p *pathTemplateParser) variable() []segment {
 | 
			
		||||
	// Simplification: treat FieldPath as LITERAL, instead of IDENT { '.' IDENT }
 | 
			
		||||
	name := p.literal()
 | 
			
		||||
	if p.seenName[name] {
 | 
			
		||||
		p.error(name + " appears multiple times")
 | 
			
		||||
	}
 | 
			
		||||
	p.seenName[name] = true
 | 
			
		||||
	var segs []segment
 | 
			
		||||
	if p.consume('=') {
 | 
			
		||||
		segs = p.segments(name)
 | 
			
		||||
	} else {
 | 
			
		||||
		// "{var}" is equivalent to "{var=*}"
 | 
			
		||||
		segs = []segment{{name: name, matcher: wildcardMatcher(0)}}
 | 
			
		||||
	}
 | 
			
		||||
	if !p.consume('}') {
 | 
			
		||||
		p.error("expected '}'")
 | 
			
		||||
	}
 | 
			
		||||
	return segs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A literal is any sequence of characters other than a few special ones.
 | 
			
		||||
// The list of stop characters is not quite the same as in the template RFC.
 | 
			
		||||
func (p *pathTemplateParser) literal() string {
 | 
			
		||||
	lit := p.consumeUntil("/*}{=")
 | 
			
		||||
	if lit == "" {
 | 
			
		||||
		p.error("empty literal")
 | 
			
		||||
	}
 | 
			
		||||
	return lit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Read runes until EOF or one of the runes in stopRunes is encountered.
 | 
			
		||||
// If the latter, unread the stop rune. Return the accumulated runes as a string.
 | 
			
		||||
func (p *pathTemplateParser) consumeUntil(stopRunes string) string {
 | 
			
		||||
	var runes []rune
 | 
			
		||||
	for {
 | 
			
		||||
		r, ok := p.readRune()
 | 
			
		||||
		if !ok {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		if strings.IndexRune(stopRunes, r) >= 0 {
 | 
			
		||||
			p.unreadRune()
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		runes = append(runes, r)
 | 
			
		||||
	}
 | 
			
		||||
	return string(runes)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// If the next rune is r, consume it and return true.
 | 
			
		||||
// Otherwise, leave the input unchanged and return false.
 | 
			
		||||
func (p *pathTemplateParser) consume(r rune) bool {
 | 
			
		||||
	rr, ok := p.readRune()
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	if r == rr {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	p.unreadRune()
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Read the next rune from the input. Return it.
 | 
			
		||||
// The second return value is false at EOF.
 | 
			
		||||
func (p *pathTemplateParser) readRune() (rune, bool) {
 | 
			
		||||
	r, _, err := p.r.ReadRune()
 | 
			
		||||
	if err == io.EOF {
 | 
			
		||||
		return r, false
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		p.error(err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	p.runeCount++
 | 
			
		||||
	return r, true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Put the last rune that was read back on the input.
 | 
			
		||||
func (p *pathTemplateParser) unreadRune() {
 | 
			
		||||
	if err := p.r.UnreadRune(); err != nil {
 | 
			
		||||
		p.error(err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	p.runeCount--
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										3
									
								
								vendor/golang.org/x/oauth2/google/appengine.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/golang.org/x/oauth2/google/appengine.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -20,6 +20,9 @@ var appengineVM bool
 | 
			
		|||
// Set at init time by appengine_hook.go. If nil, we're not on App Engine.
 | 
			
		||||
var appengineTokenFunc func(c context.Context, scopes ...string) (token string, expiry time.Time, err error)
 | 
			
		||||
 | 
			
		||||
// Set at init time by appengine_hook.go. If nil, we're not on App Engine.
 | 
			
		||||
var appengineAppIDFunc func(c context.Context) string
 | 
			
		||||
 | 
			
		||||
// AppEngineTokenSource returns a token source that fetches tokens
 | 
			
		||||
// issued to the current App Engine application's service account.
 | 
			
		||||
// If you are implementing a 3-legged OAuth 2.0 flow on App Engine
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								vendor/golang.org/x/oauth2/google/appengine_hook.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/golang.org/x/oauth2/google/appengine_hook.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -10,4 +10,5 @@ import "google.golang.org/appengine"
 | 
			
		|||
 | 
			
		||||
func init() {
 | 
			
		||||
	appengineTokenFunc = appengine.AccessToken
 | 
			
		||||
	appengineAppIDFunc = appengine.AppID
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								vendor/golang.org/x/oauth2/google/appenginevm_hook.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/golang.org/x/oauth2/google/appenginevm_hook.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -11,4 +11,5 @@ import "google.golang.org/appengine"
 | 
			
		|||
func init() {
 | 
			
		||||
	appengineVM = true
 | 
			
		||||
	appengineTokenFunc = appengine.AccessToken
 | 
			
		||||
	appengineAppIDFunc = appengine.AppID
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										115
									
								
								vendor/golang.org/x/oauth2/google/default.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										115
									
								
								vendor/golang.org/x/oauth2/google/default.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -6,7 +6,6 @@ package google
 | 
			
		|||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"net/http"
 | 
			
		||||
| 
						 | 
				
			
			@ -14,22 +13,21 @@ import (
 | 
			
		|||
	"path/filepath"
 | 
			
		||||
	"runtime"
 | 
			
		||||
 | 
			
		||||
	"cloud.google.com/go/compute/metadata"
 | 
			
		||||
	"golang.org/x/net/context"
 | 
			
		||||
	"golang.org/x/oauth2"
 | 
			
		||||
	"golang.org/x/oauth2/jwt"
 | 
			
		||||
	"google.golang.org/cloud/compute/metadata"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DefaultCredentials holds "Application Default Credentials".
 | 
			
		||||
// For more details, see:
 | 
			
		||||
// https://developers.google.com/accounts/docs/application-default-credentials
 | 
			
		||||
type DefaultCredentials struct {
 | 
			
		||||
	ProjectID   string // may be empty
 | 
			
		||||
	TokenSource oauth2.TokenSource
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DefaultClient returns an HTTP Client that uses the
 | 
			
		||||
// DefaultTokenSource to obtain authentication credentials.
 | 
			
		||||
//
 | 
			
		||||
// This client should be used when developing services
 | 
			
		||||
// that run on Google App Engine or Google Compute Engine
 | 
			
		||||
// and use "Application Default Credentials."
 | 
			
		||||
//
 | 
			
		||||
// For more details, see:
 | 
			
		||||
// https://developers.google.com/accounts/docs/application-default-credentials
 | 
			
		||||
//
 | 
			
		||||
func DefaultClient(ctx context.Context, scope ...string) (*http.Client, error) {
 | 
			
		||||
	ts, err := DefaultTokenSource(ctx, scope...)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -38,8 +36,18 @@ func DefaultClient(ctx context.Context, scope ...string) (*http.Client, error) {
 | 
			
		|||
	return oauth2.NewClient(ctx, ts), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DefaultTokenSource is a token source that uses
 | 
			
		||||
// DefaultTokenSource returns the token source for
 | 
			
		||||
// "Application Default Credentials".
 | 
			
		||||
// It is a shortcut for FindDefaultCredentials(ctx, scope).TokenSource.
 | 
			
		||||
func DefaultTokenSource(ctx context.Context, scope ...string) (oauth2.TokenSource, error) {
 | 
			
		||||
	creds, err := FindDefaultCredentials(ctx, scope...)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return creds.TokenSource, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FindDefaultCredentials searches for "Application Default Credentials".
 | 
			
		||||
//
 | 
			
		||||
// It looks for credentials in the following places,
 | 
			
		||||
// preferring the first location found:
 | 
			
		||||
| 
						 | 
				
			
			@ -53,45 +61,40 @@ func DefaultClient(ctx context.Context, scope ...string) (*http.Client, error) {
 | 
			
		|||
//   4. On Google Compute Engine and Google App Engine Managed VMs, it fetches
 | 
			
		||||
//      credentials from the metadata server.
 | 
			
		||||
//      (In this final case any provided scopes are ignored.)
 | 
			
		||||
//
 | 
			
		||||
// For more details, see:
 | 
			
		||||
// https://developers.google.com/accounts/docs/application-default-credentials
 | 
			
		||||
//
 | 
			
		||||
func DefaultTokenSource(ctx context.Context, scope ...string) (oauth2.TokenSource, error) {
 | 
			
		||||
func FindDefaultCredentials(ctx context.Context, scope ...string) (*DefaultCredentials, error) {
 | 
			
		||||
	// First, try the environment variable.
 | 
			
		||||
	const envVar = "GOOGLE_APPLICATION_CREDENTIALS"
 | 
			
		||||
	if filename := os.Getenv(envVar); filename != "" {
 | 
			
		||||
		ts, err := tokenSourceFromFile(ctx, filename, scope)
 | 
			
		||||
		creds, err := readCredentialsFile(ctx, filename, scope)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, fmt.Errorf("google: error getting credentials using %v environment variable: %v", envVar, err)
 | 
			
		||||
		}
 | 
			
		||||
		return ts, nil
 | 
			
		||||
		return creds, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Second, try a well-known file.
 | 
			
		||||
	filename := wellKnownFile()
 | 
			
		||||
	_, err := os.Stat(filename)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		ts, err2 := tokenSourceFromFile(ctx, filename, scope)
 | 
			
		||||
		if err2 == nil {
 | 
			
		||||
			return ts, nil
 | 
			
		||||
		}
 | 
			
		||||
		err = err2
 | 
			
		||||
	} else if os.IsNotExist(err) {
 | 
			
		||||
		err = nil // ignore this error
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
	if creds, err := readCredentialsFile(ctx, filename, scope); err == nil {
 | 
			
		||||
		return creds, nil
 | 
			
		||||
	} else if !os.IsNotExist(err) {
 | 
			
		||||
		return nil, fmt.Errorf("google: error getting credentials using well-known file (%v): %v", filename, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Third, if we're on Google App Engine use those credentials.
 | 
			
		||||
	if appengineTokenFunc != nil && !appengineVM {
 | 
			
		||||
		return AppEngineTokenSource(ctx, scope...), nil
 | 
			
		||||
		return &DefaultCredentials{
 | 
			
		||||
			ProjectID:   appengineAppIDFunc(ctx),
 | 
			
		||||
			TokenSource: AppEngineTokenSource(ctx, scope...),
 | 
			
		||||
		}, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Fourth, if we're on Google Compute Engine use the metadata server.
 | 
			
		||||
	if metadata.OnGCE() {
 | 
			
		||||
		return ComputeTokenSource(""), nil
 | 
			
		||||
		id, _ := metadata.ProjectID()
 | 
			
		||||
		return &DefaultCredentials{
 | 
			
		||||
			ProjectID:   id,
 | 
			
		||||
			TokenSource: ComputeTokenSource(""),
 | 
			
		||||
		}, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// None are found; return helpful error.
 | 
			
		||||
| 
						 | 
				
			
			@ -107,49 +110,21 @@ func wellKnownFile() string {
 | 
			
		|||
	return filepath.Join(guessUnixHomeDir(), ".config", "gcloud", f)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func tokenSourceFromFile(ctx context.Context, filename string, scopes []string) (oauth2.TokenSource, error) {
 | 
			
		||||
func readCredentialsFile(ctx context.Context, filename string, scopes []string) (*DefaultCredentials, error) {
 | 
			
		||||
	b, err := ioutil.ReadFile(filename)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	var d struct {
 | 
			
		||||
		// Common fields
 | 
			
		||||
		Type     string
 | 
			
		||||
		ClientID string `json:"client_id"`
 | 
			
		||||
 | 
			
		||||
		// User Credential fields
 | 
			
		||||
		ClientSecret string `json:"client_secret"`
 | 
			
		||||
		RefreshToken string `json:"refresh_token"`
 | 
			
		||||
 | 
			
		||||
		// Service Account fields
 | 
			
		||||
		ClientEmail  string `json:"client_email"`
 | 
			
		||||
		PrivateKeyID string `json:"private_key_id"`
 | 
			
		||||
		PrivateKey   string `json:"private_key"`
 | 
			
		||||
	}
 | 
			
		||||
	if err := json.Unmarshal(b, &d); err != nil {
 | 
			
		||||
	var f credentialsFile
 | 
			
		||||
	if err := json.Unmarshal(b, &f); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	switch d.Type {
 | 
			
		||||
	case "authorized_user":
 | 
			
		||||
		cfg := &oauth2.Config{
 | 
			
		||||
			ClientID:     d.ClientID,
 | 
			
		||||
			ClientSecret: d.ClientSecret,
 | 
			
		||||
			Scopes:       append([]string{}, scopes...), // copy
 | 
			
		||||
			Endpoint:     Endpoint,
 | 
			
		||||
		}
 | 
			
		||||
		tok := &oauth2.Token{RefreshToken: d.RefreshToken}
 | 
			
		||||
		return cfg.TokenSource(ctx, tok), nil
 | 
			
		||||
	case "service_account":
 | 
			
		||||
		cfg := &jwt.Config{
 | 
			
		||||
			Email:      d.ClientEmail,
 | 
			
		||||
			PrivateKey: []byte(d.PrivateKey),
 | 
			
		||||
			Scopes:     append([]string{}, scopes...), // copy
 | 
			
		||||
			TokenURL:   JWTTokenURL,
 | 
			
		||||
		}
 | 
			
		||||
		return cfg.TokenSource(ctx), nil
 | 
			
		||||
	case "":
 | 
			
		||||
		return nil, errors.New("missing 'type' field in credentials")
 | 
			
		||||
	default:
 | 
			
		||||
		return nil, fmt.Errorf("unknown credential type: %q", d.Type)
 | 
			
		||||
	ts, err := f.tokenSource(ctx, append([]string(nil), scopes...))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return &DefaultCredentials{
 | 
			
		||||
		ProjectID:   f.ProjectID,
 | 
			
		||||
		TokenSource: ts,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										91
									
								
								vendor/golang.org/x/oauth2/google/google.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										91
									
								
								vendor/golang.org/x/oauth2/google/google.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -21,9 +21,10 @@ import (
 | 
			
		|||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"cloud.google.com/go/compute/metadata"
 | 
			
		||||
	"golang.org/x/net/context"
 | 
			
		||||
	"golang.org/x/oauth2"
 | 
			
		||||
	"golang.org/x/oauth2/jwt"
 | 
			
		||||
	"google.golang.org/cloud/compute/metadata"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Endpoint is Google's OAuth 2.0 endpoint.
 | 
			
		||||
| 
						 | 
				
			
			@ -37,9 +38,10 @@ const JWTTokenURL = "https://accounts.google.com/o/oauth2/token"
 | 
			
		|||
 | 
			
		||||
// ConfigFromJSON uses a Google Developers Console client_credentials.json
 | 
			
		||||
// file to construct a config.
 | 
			
		||||
// client_credentials.json can be downloadable from https://console.developers.google.com,
 | 
			
		||||
// under "APIs & Auth" > "Credentials". Download the Web application credentials in the
 | 
			
		||||
// JSON format and provide the contents of the file as jsonKey.
 | 
			
		||||
// client_credentials.json can be downloaded from
 | 
			
		||||
// https://console.developers.google.com, under "Credentials". Download the Web
 | 
			
		||||
// application credentials in the JSON format and provide the contents of the
 | 
			
		||||
// file as jsonKey.
 | 
			
		||||
func ConfigFromJSON(jsonKey []byte, scope ...string) (*oauth2.Config, error) {
 | 
			
		||||
	type cred struct {
 | 
			
		||||
		ClientID     string   `json:"client_id"`
 | 
			
		||||
| 
						 | 
				
			
			@ -81,22 +83,77 @@ func ConfigFromJSON(jsonKey []byte, scope ...string) (*oauth2.Config, error) {
 | 
			
		|||
 | 
			
		||||
// JWTConfigFromJSON uses a Google Developers service account JSON key file to read
 | 
			
		||||
// the credentials that authorize and authenticate the requests.
 | 
			
		||||
// Create a service account on "Credentials" page under "APIs & Auth" for your
 | 
			
		||||
// project at https://console.developers.google.com to download a JSON key file.
 | 
			
		||||
// Create a service account on "Credentials" for your project at
 | 
			
		||||
// https://console.developers.google.com to download a JSON key file.
 | 
			
		||||
func JWTConfigFromJSON(jsonKey []byte, scope ...string) (*jwt.Config, error) {
 | 
			
		||||
	var key struct {
 | 
			
		||||
		Email      string `json:"client_email"`
 | 
			
		||||
		PrivateKey string `json:"private_key"`
 | 
			
		||||
	}
 | 
			
		||||
	if err := json.Unmarshal(jsonKey, &key); err != nil {
 | 
			
		||||
	var f credentialsFile
 | 
			
		||||
	if err := json.Unmarshal(jsonKey, &f); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return &jwt.Config{
 | 
			
		||||
		Email:      key.Email,
 | 
			
		||||
		PrivateKey: []byte(key.PrivateKey),
 | 
			
		||||
		Scopes:     scope,
 | 
			
		||||
		TokenURL:   JWTTokenURL,
 | 
			
		||||
	}, nil
 | 
			
		||||
	if f.Type != serviceAccountKey {
 | 
			
		||||
		return nil, fmt.Errorf("google: read JWT from JSON credentials: 'type' field is %q (expected %q)", f.Type, serviceAccountKey)
 | 
			
		||||
	}
 | 
			
		||||
	scope = append([]string(nil), scope...) // copy
 | 
			
		||||
	return f.jwtConfig(scope), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// JSON key file types.
 | 
			
		||||
const (
 | 
			
		||||
	serviceAccountKey  = "service_account"
 | 
			
		||||
	userCredentialsKey = "authorized_user"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// credentialsFile is the unmarshalled representation of a credentials file.
 | 
			
		||||
type credentialsFile struct {
 | 
			
		||||
	Type string `json:"type"` // serviceAccountKey or userCredentialsKey
 | 
			
		||||
 | 
			
		||||
	// Service Account fields
 | 
			
		||||
	ClientEmail  string `json:"client_email"`
 | 
			
		||||
	PrivateKeyID string `json:"private_key_id"`
 | 
			
		||||
	PrivateKey   string `json:"private_key"`
 | 
			
		||||
	TokenURL     string `json:"token_uri"`
 | 
			
		||||
	ProjectID    string `json:"project_id"`
 | 
			
		||||
 | 
			
		||||
	// User Credential fields
 | 
			
		||||
	// (These typically come from gcloud auth.)
 | 
			
		||||
	ClientSecret string `json:"client_secret"`
 | 
			
		||||
	ClientID     string `json:"client_id"`
 | 
			
		||||
	RefreshToken string `json:"refresh_token"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *credentialsFile) jwtConfig(scopes []string) *jwt.Config {
 | 
			
		||||
	cfg := &jwt.Config{
 | 
			
		||||
		Email:        f.ClientEmail,
 | 
			
		||||
		PrivateKey:   []byte(f.PrivateKey),
 | 
			
		||||
		PrivateKeyID: f.PrivateKeyID,
 | 
			
		||||
		Scopes:       scopes,
 | 
			
		||||
		TokenURL:     f.TokenURL,
 | 
			
		||||
	}
 | 
			
		||||
	if cfg.TokenURL == "" {
 | 
			
		||||
		cfg.TokenURL = JWTTokenURL
 | 
			
		||||
	}
 | 
			
		||||
	return cfg
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *credentialsFile) tokenSource(ctx context.Context, scopes []string) (oauth2.TokenSource, error) {
 | 
			
		||||
	switch f.Type {
 | 
			
		||||
	case serviceAccountKey:
 | 
			
		||||
		cfg := f.jwtConfig(scopes)
 | 
			
		||||
		return cfg.TokenSource(ctx), nil
 | 
			
		||||
	case userCredentialsKey:
 | 
			
		||||
		cfg := &oauth2.Config{
 | 
			
		||||
			ClientID:     f.ClientID,
 | 
			
		||||
			ClientSecret: f.ClientSecret,
 | 
			
		||||
			Scopes:       scopes,
 | 
			
		||||
			Endpoint:     Endpoint,
 | 
			
		||||
		}
 | 
			
		||||
		tok := &oauth2.Token{RefreshToken: f.RefreshToken}
 | 
			
		||||
		return cfg.TokenSource(ctx, tok), nil
 | 
			
		||||
	case "":
 | 
			
		||||
		return nil, errors.New("missing 'type' field in credentials")
 | 
			
		||||
	default:
 | 
			
		||||
		return nil, fmt.Errorf("unknown credential type: %q", f.Type)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ComputeTokenSource returns a token source that fetches access tokens
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								vendor/golang.org/x/oauth2/google/jwt.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/golang.org/x/oauth2/google/jwt.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -36,6 +36,7 @@ func JWTAccessTokenSourceFromJSON(jsonKey []byte, audience string) (oauth2.Token
 | 
			
		|||
		email:    cfg.Email,
 | 
			
		||||
		audience: audience,
 | 
			
		||||
		pk:       pk,
 | 
			
		||||
		pkID:     cfg.PrivateKeyID,
 | 
			
		||||
	}
 | 
			
		||||
	tok, err := ts.Token()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -47,6 +48,7 @@ func JWTAccessTokenSourceFromJSON(jsonKey []byte, audience string) (oauth2.Token
 | 
			
		|||
type jwtAccessTokenSource struct {
 | 
			
		||||
	email, audience string
 | 
			
		||||
	pk              *rsa.PrivateKey
 | 
			
		||||
	pkID            string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ts *jwtAccessTokenSource) Token() (*oauth2.Token, error) {
 | 
			
		||||
| 
						 | 
				
			
			@ -62,6 +64,7 @@ func (ts *jwtAccessTokenSource) Token() (*oauth2.Token, error) {
 | 
			
		|||
	hdr := &jws.Header{
 | 
			
		||||
		Algorithm: "RS256",
 | 
			
		||||
		Typ:       "JWT",
 | 
			
		||||
		KeyID:     string(ts.pkID),
 | 
			
		||||
	}
 | 
			
		||||
	msg, err := jws.Encode(hdr, cs, ts.pk)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										12
									
								
								vendor/golang.org/x/oauth2/google/sdk.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/golang.org/x/oauth2/google/sdk.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -160,9 +160,13 @@ var sdkConfigPath = func() (string, error) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func guessUnixHomeDir() string {
 | 
			
		||||
	usr, err := user.Current()
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		return usr.HomeDir
 | 
			
		||||
	// Prefer $HOME over user.Current due to glibc bug: golang.org/issue/13470
 | 
			
		||||
	if v := os.Getenv("HOME"); v != "" {
 | 
			
		||||
		return v
 | 
			
		||||
	}
 | 
			
		||||
	return os.Getenv("HOME")
 | 
			
		||||
	// Else, fall back to user.Current:
 | 
			
		||||
	if u, err := user.Current(); err == nil {
 | 
			
		||||
		return u.HomeDir
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										20
									
								
								vendor/golang.org/x/oauth2/internal/token.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								vendor/golang.org/x/oauth2/internal/token.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -92,6 +92,7 @@ func (e *expirationTime) UnmarshalJSON(b []byte) error {
 | 
			
		|||
var brokenAuthHeaderProviders = []string{
 | 
			
		||||
	"https://accounts.google.com/",
 | 
			
		||||
	"https://api.dropbox.com/",
 | 
			
		||||
	"https://api.dropboxapi.com/",
 | 
			
		||||
	"https://api.instagram.com/",
 | 
			
		||||
	"https://api.netatmo.net/",
 | 
			
		||||
	"https://api.odnoklassniki.ru/",
 | 
			
		||||
| 
						 | 
				
			
			@ -105,6 +106,7 @@ var brokenAuthHeaderProviders = []string{
 | 
			
		|||
	"https://oauth.sandbox.trainingpeaks.com/",
 | 
			
		||||
	"https://oauth.trainingpeaks.com/",
 | 
			
		||||
	"https://oauth.vk.com/",
 | 
			
		||||
	"https://openapi.baidu.com/",
 | 
			
		||||
	"https://slack.com/",
 | 
			
		||||
	"https://test-sandbox.auth.corp.google.com",
 | 
			
		||||
	"https://test.salesforce.com/",
 | 
			
		||||
| 
						 | 
				
			
			@ -113,6 +115,10 @@ var brokenAuthHeaderProviders = []string{
 | 
			
		|||
	"https://www.googleapis.com/",
 | 
			
		||||
	"https://www.linkedin.com/",
 | 
			
		||||
	"https://www.strava.com/oauth/",
 | 
			
		||||
	"https://www.wunderlist.com/oauth/",
 | 
			
		||||
	"https://api.patreon.com/",
 | 
			
		||||
	"https://sandbox.codeswholesale.com/oauth/token",
 | 
			
		||||
	"https://api.codeswholesale.com/oauth/token",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RegisterBrokenAuthHeaderProvider(tokenURL string) {
 | 
			
		||||
| 
						 | 
				
			
			@ -142,23 +148,23 @@ func providerAuthHeaderWorks(tokenURL string) bool {
 | 
			
		|||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RetrieveToken(ctx context.Context, ClientID, ClientSecret, TokenURL string, v url.Values) (*Token, error) {
 | 
			
		||||
func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string, v url.Values) (*Token, error) {
 | 
			
		||||
	hc, err := ContextClient(ctx)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	v.Set("client_id", ClientID)
 | 
			
		||||
	bustedAuth := !providerAuthHeaderWorks(TokenURL)
 | 
			
		||||
	if bustedAuth && ClientSecret != "" {
 | 
			
		||||
		v.Set("client_secret", ClientSecret)
 | 
			
		||||
	v.Set("client_id", clientID)
 | 
			
		||||
	bustedAuth := !providerAuthHeaderWorks(tokenURL)
 | 
			
		||||
	if bustedAuth && clientSecret != "" {
 | 
			
		||||
		v.Set("client_secret", clientSecret)
 | 
			
		||||
	}
 | 
			
		||||
	req, err := http.NewRequest("POST", TokenURL, strings.NewReader(v.Encode()))
 | 
			
		||||
	req, err := http.NewRequest("POST", tokenURL, strings.NewReader(v.Encode()))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
 | 
			
		||||
	if !bustedAuth {
 | 
			
		||||
		req.SetBasicAuth(ClientID, ClientSecret)
 | 
			
		||||
		req.SetBasicAuth(clientID, clientSecret)
 | 
			
		||||
	}
 | 
			
		||||
	r, err := hc.Do(req)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										60
									
								
								vendor/golang.org/x/oauth2/jws/jws.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										60
									
								
								vendor/golang.org/x/oauth2/jws/jws.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -2,8 +2,16 @@
 | 
			
		|||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// Package jws provides encoding and decoding utilities for
 | 
			
		||||
// signed JWS messages.
 | 
			
		||||
// Package jws provides a partial implementation
 | 
			
		||||
// of JSON Web Signature encoding and decoding.
 | 
			
		||||
// It exists to support the golang.org/x/oauth2 package.
 | 
			
		||||
//
 | 
			
		||||
// See RFC 7515.
 | 
			
		||||
//
 | 
			
		||||
// Deprecated: this package is not intended for public use and might be
 | 
			
		||||
// removed in the future. It exists for internal use only.
 | 
			
		||||
// Please switch to another JWS package or copy this package into your own
 | 
			
		||||
// source tree.
 | 
			
		||||
package jws // import "golang.org/x/oauth2/jws"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +72,7 @@ func (c *ClaimSet) encode() (string, error) {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	if len(c.PrivateClaims) == 0 {
 | 
			
		||||
		return base64Encode(b), nil
 | 
			
		||||
		return base64.RawURLEncoding.EncodeToString(b), nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Marshal private claim set and then append it to b.
 | 
			
		||||
| 
						 | 
				
			
			@ -82,7 +90,7 @@ func (c *ClaimSet) encode() (string, error) {
 | 
			
		|||
	}
 | 
			
		||||
	b[len(b)-1] = ','         // Replace closing curly brace with a comma.
 | 
			
		||||
	b = append(b, prv[1:]...) // Append private claims.
 | 
			
		||||
	return base64Encode(b), nil
 | 
			
		||||
	return base64.RawURLEncoding.EncodeToString(b), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Header represents the header for the signed JWS payloads.
 | 
			
		||||
| 
						 | 
				
			
			@ -92,6 +100,9 @@ type Header struct {
 | 
			
		|||
 | 
			
		||||
	// Represents the token type.
 | 
			
		||||
	Typ string `json:"typ"`
 | 
			
		||||
 | 
			
		||||
	// The optional hint of which key is being used.
 | 
			
		||||
	KeyID string `json:"kid,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *Header) encode() (string, error) {
 | 
			
		||||
| 
						 | 
				
			
			@ -99,7 +110,7 @@ func (h *Header) encode() (string, error) {
 | 
			
		|||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	return base64Encode(b), nil
 | 
			
		||||
	return base64.RawURLEncoding.EncodeToString(b), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Decode decodes a claim set from a JWS payload.
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +121,7 @@ func Decode(payload string) (*ClaimSet, error) {
 | 
			
		|||
		// TODO(jbd): Provide more context about the error.
 | 
			
		||||
		return nil, errors.New("jws: invalid token received")
 | 
			
		||||
	}
 | 
			
		||||
	decoded, err := base64Decode(s[1])
 | 
			
		||||
	decoded, err := base64.RawURLEncoding.DecodeString(s[1])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -137,7 +148,7 @@ func EncodeWithSigner(header *Header, c *ClaimSet, sg Signer) (string, error) {
 | 
			
		|||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf("%s.%s", ss, base64Encode(sig)), nil
 | 
			
		||||
	return fmt.Sprintf("%s.%s", ss, base64.RawURLEncoding.EncodeToString(sig)), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Encode encodes a signed JWS with provided header and claim set.
 | 
			
		||||
| 
						 | 
				
			
			@ -145,28 +156,27 @@ func EncodeWithSigner(header *Header, c *ClaimSet, sg Signer) (string, error) {
 | 
			
		|||
func Encode(header *Header, c *ClaimSet, key *rsa.PrivateKey) (string, error) {
 | 
			
		||||
	sg := func(data []byte) (sig []byte, err error) {
 | 
			
		||||
		h := sha256.New()
 | 
			
		||||
		h.Write([]byte(data))
 | 
			
		||||
		h.Write(data)
 | 
			
		||||
		return rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, h.Sum(nil))
 | 
			
		||||
	}
 | 
			
		||||
	return EncodeWithSigner(header, c, sg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// base64Encode returns and Base64url encoded version of the input string with any
 | 
			
		||||
// trailing "=" stripped.
 | 
			
		||||
func base64Encode(b []byte) string {
 | 
			
		||||
	return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// base64Decode decodes the Base64url encoded string
 | 
			
		||||
func base64Decode(s string) ([]byte, error) {
 | 
			
		||||
	// add back missing padding
 | 
			
		||||
	switch len(s) % 4 {
 | 
			
		||||
	case 1:
 | 
			
		||||
		s += "==="
 | 
			
		||||
	case 2:
 | 
			
		||||
		s += "=="
 | 
			
		||||
	case 3:
 | 
			
		||||
		s += "="
 | 
			
		||||
// Verify tests whether the provided JWT token's signature was produced by the private key
 | 
			
		||||
// associated with the supplied public key.
 | 
			
		||||
func Verify(token string, key *rsa.PublicKey) error {
 | 
			
		||||
	parts := strings.Split(token, ".")
 | 
			
		||||
	if len(parts) != 3 {
 | 
			
		||||
		return errors.New("jws: invalid token received, token must have 3 parts")
 | 
			
		||||
	}
 | 
			
		||||
	return base64.URLEncoding.DecodeString(s)
 | 
			
		||||
 | 
			
		||||
	signedContent := parts[0] + "." + parts[1]
 | 
			
		||||
	signatureString, err := base64.RawURLEncoding.DecodeString(parts[2])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	h := sha256.New()
 | 
			
		||||
	h.Write([]byte(signedContent))
 | 
			
		||||
	return rsa.VerifyPKCS1v15(key, crypto.SHA256, h.Sum(nil), []byte(signatureString))
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										4
									
								
								vendor/golang.org/x/oauth2/jwt/jwt.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/golang.org/x/oauth2/jwt/jwt.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -46,6 +46,10 @@ type Config struct {
 | 
			
		|||
	//
 | 
			
		||||
	PrivateKey []byte
 | 
			
		||||
 | 
			
		||||
	// PrivateKeyID contains an optional hint indicating which key is being
 | 
			
		||||
	// used.
 | 
			
		||||
	PrivateKeyID string
 | 
			
		||||
 | 
			
		||||
	// Subject is the optional user to impersonate.
 | 
			
		||||
	Subject string
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										6
									
								
								vendor/golang.org/x/oauth2/oauth2.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/golang.org/x/oauth2/oauth2.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -21,6 +21,8 @@ import (
 | 
			
		|||
 | 
			
		||||
// NoContext is the default context you should supply if not using
 | 
			
		||||
// your own context.Context (see https://golang.org/x/net/context).
 | 
			
		||||
//
 | 
			
		||||
// Deprecated: Use context.Background() or context.TODO() instead.
 | 
			
		||||
var NoContext = context.TODO()
 | 
			
		||||
 | 
			
		||||
// RegisterBrokenAuthHeaderProvider registers an OAuth2 server
 | 
			
		||||
| 
						 | 
				
			
			@ -37,6 +39,8 @@ func RegisterBrokenAuthHeaderProvider(tokenURL string) {
 | 
			
		|||
 | 
			
		||||
// Config describes a typical 3-legged OAuth2 flow, with both the
 | 
			
		||||
// client application information and the server's endpoint URLs.
 | 
			
		||||
// For the client credentials 2-legged OAuth2 flow, see the clientcredentials
 | 
			
		||||
// package (https://golang.org/x/oauth2/clientcredentials).
 | 
			
		||||
type Config struct {
 | 
			
		||||
	// ClientID is the application's ID.
 | 
			
		||||
	ClientID string
 | 
			
		||||
| 
						 | 
				
			
			@ -295,7 +299,7 @@ func NewClient(ctx context.Context, src TokenSource) *http.Client {
 | 
			
		|||
	if src == nil {
 | 
			
		||||
		c, err := internal.ContextClient(ctx)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return &http.Client{Transport: internal.ErrorTransport{err}}
 | 
			
		||||
			return &http.Client{Transport: internal.ErrorTransport{Err: err}}
 | 
			
		||||
		}
 | 
			
		||||
		return c
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue