mirror of
https://github.com/willnorris/imageproxy.git
synced 2026-04-29 14:56:25 +02:00
update all vendored dependencies
This commit is contained in:
parent
0c20cbe5b5
commit
1933f5bf1c
284 changed files with 37534 additions and 11024 deletions
73
vendor/github.com/Azure/azure-sdk-for-go/storage/README.md
generated
vendored
Normal file
73
vendor/github.com/Azure/azure-sdk-for-go/storage/README.md
generated
vendored
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
# Azure Storage SDK for Go
|
||||
|
||||
The `github.com/Azure/azure-sdk-for-go/storage` package is used to perform REST operations against the [Azure Storage Service](https://docs.microsoft.com/en-us/azure/storage/). To manage your storage accounts (Azure Resource Manager / ARM), use the [github.com/Azure/azure-sdk-for-go/arm/storage](https://github.com/Azure/azure-sdk-for-go/tree/master/arm/storage) package. For your classic storage accounts (Azure Service Management / ASM), use [github.com/Azure/azure-sdk-for-go/management/storageservice](https://github.com/Azure/azure-sdk-for-go/tree/master/management/storageservice) package.
|
||||
|
||||
This package includes support for [Azure Storage Emulator](https://azure.microsoft.com/documentation/articles/storage-use-emulator/).
|
||||
|
||||
# Getting Started
|
||||
|
||||
1. Go get the SDK `go get -u github.com/Azure/azure-sdk-for-go/storage`
|
||||
1. If you don't already have one, [create a Storage Account](https://docs.microsoft.com/en-us/azure/storage/storage-create-storage-account).
|
||||
- Take note of your Azure Storage Account Name and Azure Storage Account Key. They'll both be necessary for using this library.
|
||||
- This option is production ready, but can also be used for development.
|
||||
1. (Optional, Windows only) Download and start the [Azure Storage Emulator](https://azure.microsoft.com/documentation/articles/storage-use-emulator/).
|
||||
1. Checkout our existing [samples](https://github.com/Azure-Samples?q=Storage&language=go).
|
||||
|
||||
# Contributing
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||
|
||||
When contributing, please conform to the following practices:
|
||||
- Run [gofmt](https://golang.org/cmd/gofmt/) to use standard go formatting.
|
||||
- Run [golint](https://github.com/golang/lint) to conform to standard naming conventions.
|
||||
- Run [go vet](https://golang.org/cmd/vet/) to catch common Go mistakes.
|
||||
- Use [GoASTScanner/gas](https://github.com/GoASTScanner/gas) to ensure there are no common security violations in your contribution.
|
||||
- Run [go test](https://golang.org/cmd/go/#hdr-Test_packages) to catch possible bugs in the code: `go test ./storage/...`.
|
||||
- This project uses HTTP recordings for testing.
|
||||
- The recorder should be attached to the client before calling the functions to test and later stopped.
|
||||
- If you updated an existing test, its recording might need to be updated. Run `go test ./storage/... -ow -check.f TestName` to rerecord the test.
|
||||
- Important note: all HTTP requests in the recording must be unique: different bodies, headers (`User-Agent`, `Authorization` and `Date` or `x-ms-date` headers are ignored), URLs and methods. As opposed to the example above, the following test is not suitable for recording:
|
||||
|
||||
``` go
|
||||
func (s *StorageQueueSuite) TestQueueExists(c *chk.C) {
|
||||
cli := getQueueClient(c)
|
||||
rec := cli.client.appendRecorder(c)
|
||||
defer rec.Stop()
|
||||
|
||||
queue := cli.GetQueueReference(queueName(c))
|
||||
ok, err := queue.Exists()
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(ok, chk.Equals, false)
|
||||
|
||||
c.Assert(queue.Create(nil), chk.IsNil)
|
||||
defer queue.Delete(nil)
|
||||
|
||||
ok, err = queue.Exists() // This is the very same request as the one 5 lines above
|
||||
// The test replayer gets confused and the test fails in the last line
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(ok, chk.Equals, true)
|
||||
}
|
||||
```
|
||||
|
||||
- On the other side, this test does not repeat requests: the URLs are different.
|
||||
|
||||
``` go
|
||||
func (s *StorageQueueSuite) TestQueueExists(c *chk.C) {
|
||||
cli := getQueueClient(c)
|
||||
rec := cli.client.appendRecorder(c)
|
||||
defer rec.Stop()
|
||||
|
||||
queue1 := cli.GetQueueReference(queueName(c, "nonexistent"))
|
||||
ok, err := queue1.Exists()
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(ok, chk.Equals, false)
|
||||
|
||||
queue2 := cli.GetQueueReference(queueName(c, "exisiting"))
|
||||
c.Assert(queue2.Create(nil), chk.IsNil)
|
||||
defer queue2.Delete(nil)
|
||||
|
||||
ok, err = queue2.Exists()
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(ok, chk.Equals, true)
|
||||
}
|
||||
```
|
||||
27
vendor/github.com/Azure/azure-sdk-for-go/storage/appendblob.go
generated
vendored
27
vendor/github.com/Azure/azure-sdk-for-go/storage/appendblob.go
generated
vendored
|
|
@ -1,7 +1,23 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
|
@ -31,8 +47,7 @@ func (b *Blob) PutAppendBlob(options *PutBlobOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusCreated})
|
||||
return b.respondCreation(resp, BlobTypeAppend)
|
||||
}
|
||||
|
||||
// AppendBlockOptions includes the options for an append block operation
|
||||
|
|
@ -46,6 +61,7 @@ type AppendBlockOptions struct {
|
|||
IfMatch string `header:"If-Match"`
|
||||
IfNoneMatch string `header:"If-None-Match"`
|
||||
RequestID string `header:"x-ms-client-request-id"`
|
||||
ContentMD5 bool
|
||||
}
|
||||
|
||||
// AppendBlock appends a block to an append blob.
|
||||
|
|
@ -60,6 +76,10 @@ func (b *Blob) AppendBlock(chunk []byte, options *AppendBlockOptions) error {
|
|||
if options != nil {
|
||||
params = addTimeout(params, options.Timeout)
|
||||
headers = mergeHeaders(headers, headersFromStruct(*options))
|
||||
if options.ContentMD5 {
|
||||
md5sum := md5.Sum(chunk)
|
||||
headers[headerContentMD5] = base64.StdEncoding.EncodeToString(md5sum[:])
|
||||
}
|
||||
}
|
||||
uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params)
|
||||
|
||||
|
|
@ -67,6 +87,5 @@ func (b *Blob) AppendBlock(chunk []byte, options *AppendBlockOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusCreated})
|
||||
return b.respondCreation(resp, BlobTypeAppend)
|
||||
}
|
||||
|
|
|
|||
24
vendor/github.com/Azure/azure-sdk-for-go/storage/authorization.go
generated
vendored
24
vendor/github.com/Azure/azure-sdk-for-go/storage/authorization.go
generated
vendored
|
|
@ -1,6 +1,20 @@
|
|||
// Package storage provides clients for Microsoft Azure Storage Services.
|
||||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
|
@ -41,11 +55,13 @@ const (
|
|||
)
|
||||
|
||||
func (c *Client) addAuthorizationHeader(verb, url string, headers map[string]string, auth authentication) (map[string]string, error) {
|
||||
authHeader, err := c.getSharedKey(verb, url, headers, auth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if !c.sasClient {
|
||||
authHeader, err := c.getSharedKey(verb, url, headers, auth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
headers[headerAuthorization] = authHeader
|
||||
}
|
||||
headers[headerAuthorization] = authHeader
|
||||
return headers, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
55
vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go
generated
vendored
55
vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
|
|
@ -90,7 +104,7 @@ type BlobProperties struct {
|
|||
CacheControl string `xml:"Cache-Control" header:"x-ms-blob-cache-control"`
|
||||
ContentLanguage string `xml:"Cache-Language" header:"x-ms-blob-content-language"`
|
||||
ContentDisposition string `xml:"Content-Disposition" header:"x-ms-blob-content-disposition"`
|
||||
BlobType BlobType `xml:"x-ms-blob-blob-type"`
|
||||
BlobType BlobType `xml:"BlobType"`
|
||||
SequenceNumber int64 `xml:"x-ms-blob-sequence-number"`
|
||||
CopyID string `xml:"CopyId"`
|
||||
CopyStatus string `xml:"CopyStatus"`
|
||||
|
|
@ -135,8 +149,7 @@ func (b *Blob) Exists() (bool, error) {
|
|||
}
|
||||
|
||||
// GetURL gets the canonical URL to the blob with the specified name in the
|
||||
// specified container. If name is not specified, the canonical URL for the entire
|
||||
// container is obtained.
|
||||
// specified container.
|
||||
// This method does not create a publicly accessible URL if the blob or container
|
||||
// is private and this method does not check if the blob exists.
|
||||
func (b *Blob) GetURL() string {
|
||||
|
|
@ -437,8 +450,8 @@ func (b *Blob) SetProperties(options *SetBlobPropertiesOptions) error {
|
|||
uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params)
|
||||
|
||||
if b.Properties.BlobType == BlobTypePage {
|
||||
headers = addToHeaders(headers, "x-ms-blob-content-length", fmt.Sprintf("byte %v", b.Properties.ContentLength))
|
||||
if options != nil || options.SequenceNumberAction != nil {
|
||||
headers = addToHeaders(headers, "x-ms-blob-content-length", fmt.Sprintf("%v", b.Properties.ContentLength))
|
||||
if options != nil && options.SequenceNumberAction != nil {
|
||||
headers = addToHeaders(headers, "x-ms-sequence-number-action", string(*options.SequenceNumberAction))
|
||||
if *options.SequenceNumberAction != SequenceNumberActionIncrement {
|
||||
headers = addToHeaders(headers, "x-ms-blob-sequence-number", fmt.Sprintf("%v", b.Properties.SequenceNumber))
|
||||
|
|
@ -536,27 +549,7 @@ func (b *Blob) GetMetadata(options *GetBlobMetadataOptions) error {
|
|||
}
|
||||
|
||||
func (b *Blob) writeMetadata(h http.Header) {
|
||||
metadata := make(map[string]string)
|
||||
for k, v := range h {
|
||||
// Can't trust CanonicalHeaderKey() to munge case
|
||||
// reliably. "_" is allowed in identifiers:
|
||||
// https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx
|
||||
// https://msdn.microsoft.com/library/aa664670(VS.71).aspx
|
||||
// http://tools.ietf.org/html/rfc7230#section-3.2
|
||||
// ...but "_" is considered invalid by
|
||||
// CanonicalMIMEHeaderKey in
|
||||
// https://golang.org/src/net/textproto/reader.go?s=14615:14659#L542
|
||||
// so k can be "X-Ms-Meta-Lol" or "x-ms-meta-lol_rofl".
|
||||
k = strings.ToLower(k)
|
||||
if len(v) == 0 || !strings.HasPrefix(k, strings.ToLower(userDefinedMetadataHeaderPrefix)) {
|
||||
continue
|
||||
}
|
||||
// metadata["lol"] = content of the last X-Ms-Meta-Lol header
|
||||
k = k[len(userDefinedMetadataHeaderPrefix):]
|
||||
metadata[k] = v[len(v)-1]
|
||||
}
|
||||
|
||||
b.Metadata = BlobMetadata(metadata)
|
||||
b.Metadata = BlobMetadata(writeMetadata(h))
|
||||
}
|
||||
|
||||
// DeleteBlobOptions includes the options for a delete blob operation
|
||||
|
|
@ -627,3 +620,13 @@ func pathForResource(container, name string) string {
|
|||
}
|
||||
return fmt.Sprintf("/%s", container)
|
||||
}
|
||||
|
||||
func (b *Blob) respondCreation(resp *storageResponse, bt BlobType) error {
|
||||
readAndCloseBody(resp.body)
|
||||
err := checkRespCode(resp.statusCode, []int{http.StatusCreated})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.Properties.BlobType = bt
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
150
vendor/github.com/Azure/azure-sdk-for-go/storage/blobsasuri.go
generated
vendored
150
vendor/github.com/Azure/azure-sdk-for-go/storage/blobsasuri.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
|
@ -8,70 +22,122 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// GetSASURIWithSignedIPAndProtocol creates an URL to the specified blob which contains the Shared
|
||||
// Access Signature with specified permissions and expiration time. Also includes signedIPRange and allowed protocols.
|
||||
// If old API version is used but no signedIP is passed (ie empty string) then this should still work.
|
||||
// We only populate the signedIP when it non-empty.
|
||||
// OverrideHeaders defines overridable response heaedrs in
|
||||
// a request using a SAS URI.
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas
|
||||
type OverrideHeaders struct {
|
||||
CacheControl string
|
||||
ContentDisposition string
|
||||
ContentEncoding string
|
||||
ContentLanguage string
|
||||
ContentType string
|
||||
}
|
||||
|
||||
// BlobSASOptions are options to construct a blob SAS
|
||||
// URI.
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas
|
||||
type BlobSASOptions struct {
|
||||
BlobServiceSASPermissions
|
||||
OverrideHeaders
|
||||
SASOptions
|
||||
}
|
||||
|
||||
// BlobServiceSASPermissions includes the available permissions for
|
||||
// blob service SAS URI.
|
||||
type BlobServiceSASPermissions struct {
|
||||
Read bool
|
||||
Add bool
|
||||
Create bool
|
||||
Write bool
|
||||
Delete bool
|
||||
}
|
||||
|
||||
func (p BlobServiceSASPermissions) buildString() string {
|
||||
permissions := ""
|
||||
if p.Read {
|
||||
permissions += "r"
|
||||
}
|
||||
if p.Add {
|
||||
permissions += "a"
|
||||
}
|
||||
if p.Create {
|
||||
permissions += "c"
|
||||
}
|
||||
if p.Write {
|
||||
permissions += "w"
|
||||
}
|
||||
if p.Delete {
|
||||
permissions += "d"
|
||||
}
|
||||
return permissions
|
||||
}
|
||||
|
||||
// GetSASURI creates an URL to the blob which contains the Shared
|
||||
// Access Signature with the specified options.
|
||||
//
|
||||
// See https://msdn.microsoft.com/en-us/library/azure/ee395415.aspx
|
||||
func (b *Blob) GetSASURIWithSignedIPAndProtocol(expiry time.Time, permissions string, signedIPRange string, HTTPSOnly bool) (string, error) {
|
||||
var (
|
||||
signedPermissions = permissions
|
||||
blobURL = b.GetURL()
|
||||
)
|
||||
canonicalizedResource, err := b.Container.bsc.client.buildCanonicalizedResource(blobURL, b.Container.bsc.auth, true)
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas
|
||||
func (b *Blob) GetSASURI(options BlobSASOptions) (string, error) {
|
||||
uri := b.GetURL()
|
||||
signedResource := "b"
|
||||
canonicalizedResource, err := b.Container.bsc.client.buildCanonicalizedResource(uri, b.Container.bsc.auth, true)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// "The canonicalizedresouce portion of the string is a canonical path to the signed resource.
|
||||
// It must include the service name (blob, table, queue or file) for version 2015-02-21 or
|
||||
// later, the storage account name, and the resource name, and must be URL-decoded.
|
||||
// -- https://msdn.microsoft.com/en-us/library/azure/dn140255.aspx
|
||||
permissions := options.BlobServiceSASPermissions.buildString()
|
||||
return b.Container.bsc.client.blobAndFileSASURI(options.SASOptions, uri, permissions, canonicalizedResource, signedResource, options.OverrideHeaders)
|
||||
}
|
||||
|
||||
func (c *Client) blobAndFileSASURI(options SASOptions, uri, permissions, canonicalizedResource, signedResource string, headers OverrideHeaders) (string, error) {
|
||||
start := ""
|
||||
if options.Start != (time.Time{}) {
|
||||
start = options.Start.UTC().Format(time.RFC3339)
|
||||
}
|
||||
|
||||
expiry := options.Expiry.UTC().Format(time.RFC3339)
|
||||
|
||||
// We need to replace + with %2b first to avoid being treated as a space (which is correct for query strings, but not the path component).
|
||||
canonicalizedResource = strings.Replace(canonicalizedResource, "+", "%2b", -1)
|
||||
canonicalizedResource, err = url.QueryUnescape(canonicalizedResource)
|
||||
canonicalizedResource, err := url.QueryUnescape(canonicalizedResource)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
signedExpiry := expiry.UTC().Format(time.RFC3339)
|
||||
|
||||
//If blob name is missing, resource is a container
|
||||
signedResource := "c"
|
||||
if len(b.Name) > 0 {
|
||||
signedResource = "b"
|
||||
}
|
||||
|
||||
protocols := ""
|
||||
if HTTPSOnly {
|
||||
if options.UseHTTPS {
|
||||
protocols = "https"
|
||||
}
|
||||
stringToSign, err := blobSASStringToSign(b.Container.bsc.client.apiVersion, canonicalizedResource, signedExpiry, signedPermissions, signedIPRange, protocols)
|
||||
stringToSign, err := blobSASStringToSign(permissions, start, expiry, canonicalizedResource, options.Identifier, options.IP, protocols, c.apiVersion, headers)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
sig := b.Container.bsc.client.computeHmac256(stringToSign)
|
||||
sig := c.computeHmac256(stringToSign)
|
||||
sasParams := url.Values{
|
||||
"sv": {b.Container.bsc.client.apiVersion},
|
||||
"se": {signedExpiry},
|
||||
"sv": {c.apiVersion},
|
||||
"se": {expiry},
|
||||
"sr": {signedResource},
|
||||
"sp": {signedPermissions},
|
||||
"sp": {permissions},
|
||||
"sig": {sig},
|
||||
}
|
||||
|
||||
if b.Container.bsc.client.apiVersion >= "2015-04-05" {
|
||||
if c.apiVersion >= "2015-04-05" {
|
||||
if protocols != "" {
|
||||
sasParams.Add("spr", protocols)
|
||||
}
|
||||
if signedIPRange != "" {
|
||||
sasParams.Add("sip", signedIPRange)
|
||||
if options.IP != "" {
|
||||
sasParams.Add("sip", options.IP)
|
||||
}
|
||||
}
|
||||
|
||||
sasURL, err := url.Parse(blobURL)
|
||||
// Add override response hedaers
|
||||
addQueryParameter(sasParams, "rscc", headers.CacheControl)
|
||||
addQueryParameter(sasParams, "rscd", headers.ContentDisposition)
|
||||
addQueryParameter(sasParams, "rsce", headers.ContentEncoding)
|
||||
addQueryParameter(sasParams, "rscl", headers.ContentLanguage)
|
||||
addQueryParameter(sasParams, "rsct", headers.ContentType)
|
||||
|
||||
sasURL, err := url.Parse(uri)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
@ -79,16 +145,12 @@ func (b *Blob) GetSASURIWithSignedIPAndProtocol(expiry time.Time, permissions st
|
|||
return sasURL.String(), nil
|
||||
}
|
||||
|
||||
// GetSASURI creates an URL to the specified blob which contains the Shared
|
||||
// Access Signature with specified permissions and expiration time.
|
||||
//
|
||||
// See https://msdn.microsoft.com/en-us/library/azure/ee395415.aspx
|
||||
func (b *Blob) GetSASURI(expiry time.Time, permissions string) (string, error) {
|
||||
return b.GetSASURIWithSignedIPAndProtocol(expiry, permissions, "", false)
|
||||
}
|
||||
|
||||
func blobSASStringToSign(signedVersion, canonicalizedResource, signedExpiry, signedPermissions string, signedIP string, protocols string) (string, error) {
|
||||
var signedStart, signedIdentifier, rscc, rscd, rsce, rscl, rsct string
|
||||
func blobSASStringToSign(signedPermissions, signedStart, signedExpiry, canonicalizedResource, signedIdentifier, signedIP, protocols, signedVersion string, headers OverrideHeaders) (string, error) {
|
||||
rscc := headers.CacheControl
|
||||
rscd := headers.ContentDisposition
|
||||
rsce := headers.ContentEncoding
|
||||
rscl := headers.ContentLanguage
|
||||
rsct := headers.ContentType
|
||||
|
||||
if signedVersion >= "2015-02-21" {
|
||||
canonicalizedResource = "/blob" + canonicalizedResource
|
||||
|
|
|
|||
97
vendor/github.com/Azure/azure-sdk-for-go/storage/blobserviceclient.go
generated
vendored
97
vendor/github.com/Azure/azure-sdk-for-go/storage/blobserviceclient.go
generated
vendored
|
|
@ -1,9 +1,26 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// BlobStorageClient contains operations for Microsoft Azure Blob Storage
|
||||
|
|
@ -45,6 +62,21 @@ func (b *BlobStorageClient) GetContainerReference(name string) *Container {
|
|||
}
|
||||
}
|
||||
|
||||
// GetContainerReferenceFromSASURI returns a Container object for the specified
|
||||
// container SASURI
|
||||
func GetContainerReferenceFromSASURI(sasuri url.URL) (*Container, error) {
|
||||
path := strings.Split(sasuri.Path, "/")
|
||||
if len(path) <= 1 {
|
||||
return nil, fmt.Errorf("could not find a container in URI: %s", sasuri.String())
|
||||
}
|
||||
cli := newSASClient().GetBlobService()
|
||||
return &Container{
|
||||
bsc: &cli,
|
||||
Name: path[1],
|
||||
sasuri: sasuri,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ListContainers returns the list of containers in a storage account along with
|
||||
// pagination token and other response details.
|
||||
//
|
||||
|
|
@ -54,21 +86,53 @@ func (b BlobStorageClient) ListContainers(params ListContainersParameters) (*Con
|
|||
uri := b.client.getEndpoint(blobServiceName, "", q)
|
||||
headers := b.client.getStandardHeaders()
|
||||
|
||||
var out ContainerListResponse
|
||||
type ContainerAlias struct {
|
||||
bsc *BlobStorageClient
|
||||
Name string `xml:"Name"`
|
||||
Properties ContainerProperties `xml:"Properties"`
|
||||
Metadata BlobMetadata
|
||||
sasuri url.URL
|
||||
}
|
||||
type ContainerListResponseAlias struct {
|
||||
XMLName xml.Name `xml:"EnumerationResults"`
|
||||
Xmlns string `xml:"xmlns,attr"`
|
||||
Prefix string `xml:"Prefix"`
|
||||
Marker string `xml:"Marker"`
|
||||
NextMarker string `xml:"NextMarker"`
|
||||
MaxResults int64 `xml:"MaxResults"`
|
||||
Containers []ContainerAlias `xml:"Containers>Container"`
|
||||
}
|
||||
|
||||
var outAlias ContainerListResponseAlias
|
||||
resp, err := b.client.exec(http.MethodGet, uri, headers, nil, b.auth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.body.Close()
|
||||
err = xmlUnmarshal(resp.body, &out)
|
||||
err = xmlUnmarshal(resp.body, &outAlias)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// assign our client to the newly created Container objects
|
||||
for i := range out.Containers {
|
||||
out.Containers[i].bsc = &b
|
||||
out := ContainerListResponse{
|
||||
XMLName: outAlias.XMLName,
|
||||
Xmlns: outAlias.Xmlns,
|
||||
Prefix: outAlias.Prefix,
|
||||
Marker: outAlias.Marker,
|
||||
NextMarker: outAlias.NextMarker,
|
||||
MaxResults: outAlias.MaxResults,
|
||||
Containers: make([]Container, len(outAlias.Containers)),
|
||||
}
|
||||
for i, cnt := range outAlias.Containers {
|
||||
out.Containers[i] = Container{
|
||||
bsc: &b,
|
||||
Name: cnt.Name,
|
||||
Properties: cnt.Properties,
|
||||
Metadata: map[string]string(cnt.Metadata),
|
||||
sasuri: cnt.sasuri,
|
||||
}
|
||||
}
|
||||
|
||||
return &out, err
|
||||
}
|
||||
|
||||
|
|
@ -93,3 +157,26 @@ func (p ListContainersParameters) getParameters() url.Values {
|
|||
|
||||
return out
|
||||
}
|
||||
|
||||
func writeMetadata(h http.Header) map[string]string {
|
||||
metadata := make(map[string]string)
|
||||
for k, v := range h {
|
||||
// Can't trust CanonicalHeaderKey() to munge case
|
||||
// reliably. "_" is allowed in identifiers:
|
||||
// https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx
|
||||
// https://msdn.microsoft.com/library/aa664670(VS.71).aspx
|
||||
// http://tools.ietf.org/html/rfc7230#section-3.2
|
||||
// ...but "_" is considered invalid by
|
||||
// CanonicalMIMEHeaderKey in
|
||||
// https://golang.org/src/net/textproto/reader.go?s=14615:14659#L542
|
||||
// so k can be "X-Ms-Meta-Lol" or "x-ms-meta-lol_rofl".
|
||||
k = strings.ToLower(k)
|
||||
if len(v) == 0 || !strings.HasPrefix(k, strings.ToLower(userDefinedMetadataHeaderPrefix)) {
|
||||
continue
|
||||
}
|
||||
// metadata["lol"] = content of the last X-Ms-Meta-Lol header
|
||||
k = k[len(userDefinedMetadataHeaderPrefix):]
|
||||
metadata[k] = v[len(v)-1]
|
||||
}
|
||||
return metadata
|
||||
}
|
||||
|
|
|
|||
20
vendor/github.com/Azure/azure-sdk-for-go/storage/blockblob.go
generated
vendored
20
vendor/github.com/Azure/azure-sdk-for-go/storage/blockblob.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
|
|
@ -132,8 +146,7 @@ func (b *Blob) CreateBlockBlobFromReader(blob io.Reader, options *PutBlobOptions
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusCreated})
|
||||
return b.respondCreation(resp, BlobTypeBlock)
|
||||
}
|
||||
|
||||
// PutBlockOptions includes the options for a put block operation
|
||||
|
|
@ -181,8 +194,7 @@ func (b *Blob) PutBlockWithLength(blockID string, size uint64, blob io.Reader, o
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusCreated})
|
||||
return b.respondCreation(resp, BlobTypeBlock)
|
||||
}
|
||||
|
||||
// PutBlockListOptions includes the options for a put block list operation
|
||||
|
|
|
|||
365
vendor/github.com/Azure/azure-sdk-for-go/storage/client.go
generated
vendored
365
vendor/github.com/Azure/azure-sdk-for-go/storage/client.go
generated
vendored
|
|
@ -1,6 +1,20 @@
|
|||
// Package storage provides clients for Microsoft Azure Storage Services.
|
||||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
|
|
@ -17,6 +31,7 @@ import (
|
|||
"net/url"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
|
@ -33,7 +48,9 @@ const (
|
|||
// basic client is created.
|
||||
DefaultAPIVersion = "2016-05-31"
|
||||
|
||||
defaultUseHTTPS = true
|
||||
defaultUseHTTPS = true
|
||||
defaultRetryAttempts = 5
|
||||
defaultRetryDuration = time.Second * 5
|
||||
|
||||
// StorageEmulatorAccountName is the fixed storage account used by Azure Storage Emulator
|
||||
StorageEmulatorAccountName = "devstoreaccount1"
|
||||
|
|
@ -53,10 +70,28 @@ const (
|
|||
userAgentHeader = "User-Agent"
|
||||
|
||||
userDefinedMetadataHeaderPrefix = "x-ms-meta-"
|
||||
|
||||
connectionStringAccountName = "accountname"
|
||||
connectionStringAccountKey = "accountkey"
|
||||
connectionStringEndpointSuffix = "endpointsuffix"
|
||||
connectionStringEndpointProtocol = "defaultendpointsprotocol"
|
||||
|
||||
connectionStringBlobEndpoint = "blobendpoint"
|
||||
connectionStringFileEndpoint = "fileendpoint"
|
||||
connectionStringQueueEndpoint = "queueendpoint"
|
||||
connectionStringTableEndpoint = "tableendpoint"
|
||||
connectionStringSAS = "sharedaccesssignature"
|
||||
)
|
||||
|
||||
var (
|
||||
validStorageAccount = regexp.MustCompile("^[0-9a-z]{3,24}$")
|
||||
validStorageAccount = regexp.MustCompile("^[0-9a-z]{3,24}$")
|
||||
defaultValidStatusCodes = []int{
|
||||
http.StatusRequestTimeout, // 408
|
||||
http.StatusInternalServerError, // 500
|
||||
http.StatusBadGateway, // 502
|
||||
http.StatusServiceUnavailable, // 503
|
||||
http.StatusGatewayTimeout, // 504
|
||||
}
|
||||
)
|
||||
|
||||
// Sender sends a request
|
||||
|
|
@ -112,6 +147,8 @@ type Client struct {
|
|||
baseURL string
|
||||
apiVersion string
|
||||
userAgent string
|
||||
sasClient bool
|
||||
accountSASToken url.Values
|
||||
}
|
||||
|
||||
type storageResponse struct {
|
||||
|
|
@ -179,6 +216,55 @@ func (e UnexpectedStatusCodeError) Got() int {
|
|||
return e.got
|
||||
}
|
||||
|
||||
// NewClientFromConnectionString creates a Client from the connection string.
|
||||
func NewClientFromConnectionString(input string) (Client, error) {
|
||||
// build a map of connection string key/value pairs
|
||||
parts := map[string]string{}
|
||||
for _, pair := range strings.Split(input, ";") {
|
||||
if pair == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
equalDex := strings.IndexByte(pair, '=')
|
||||
if equalDex <= 0 {
|
||||
return Client{}, fmt.Errorf("Invalid connection segment %q", pair)
|
||||
}
|
||||
|
||||
value := strings.TrimSpace(pair[equalDex+1:])
|
||||
key := strings.TrimSpace(strings.ToLower(pair[:equalDex]))
|
||||
parts[key] = value
|
||||
}
|
||||
|
||||
// TODO: validate parameter sets?
|
||||
|
||||
if parts[connectionStringAccountName] == StorageEmulatorAccountName {
|
||||
return NewEmulatorClient()
|
||||
}
|
||||
|
||||
if parts[connectionStringSAS] != "" {
|
||||
endpoint := ""
|
||||
if parts[connectionStringBlobEndpoint] != "" {
|
||||
endpoint = parts[connectionStringBlobEndpoint]
|
||||
} else if parts[connectionStringFileEndpoint] != "" {
|
||||
endpoint = parts[connectionStringFileEndpoint]
|
||||
} else if parts[connectionStringQueueEndpoint] != "" {
|
||||
endpoint = parts[connectionStringQueueEndpoint]
|
||||
} else {
|
||||
endpoint = parts[connectionStringTableEndpoint]
|
||||
}
|
||||
|
||||
return NewAccountSASClientFromEndpointToken(endpoint, parts[connectionStringSAS])
|
||||
}
|
||||
|
||||
useHTTPS := defaultUseHTTPS
|
||||
if parts[connectionStringEndpointProtocol] != "" {
|
||||
useHTTPS = parts[connectionStringEndpointProtocol] == "https"
|
||||
}
|
||||
|
||||
return NewClient(parts[connectionStringAccountName], parts[connectionStringAccountKey],
|
||||
parts[connectionStringEndpointSuffix], DefaultAPIVersion, useHTTPS)
|
||||
}
|
||||
|
||||
// NewBasicClient constructs a Client with given storage service name and
|
||||
// key.
|
||||
func NewBasicClient(accountName, accountKey string) (Client, error) {
|
||||
|
|
@ -206,13 +292,13 @@ func NewEmulatorClient() (Client, error) {
|
|||
// NewClient constructs a Client. This should be used if the caller wants
|
||||
// to specify whether to use HTTPS, a specific REST API version or a custom
|
||||
// storage endpoint than Azure Public Cloud.
|
||||
func NewClient(accountName, accountKey, blobServiceBaseURL, apiVersion string, useHTTPS bool) (Client, error) {
|
||||
func NewClient(accountName, accountKey, serviceBaseURL, apiVersion string, useHTTPS bool) (Client, error) {
|
||||
var c Client
|
||||
if !IsValidStorageAccount(accountName) {
|
||||
return c, fmt.Errorf("azure: account name is not valid: it must be between 3 and 24 characters, and only may contain numbers and lowercase letters: %v", accountName)
|
||||
} else if accountKey == "" {
|
||||
return c, fmt.Errorf("azure: account key required")
|
||||
} else if blobServiceBaseURL == "" {
|
||||
} else if serviceBaseURL == "" {
|
||||
return c, fmt.Errorf("azure: base storage service url required")
|
||||
}
|
||||
|
||||
|
|
@ -226,19 +312,14 @@ func NewClient(accountName, accountKey, blobServiceBaseURL, apiVersion string, u
|
|||
accountName: accountName,
|
||||
accountKey: key,
|
||||
useHTTPS: useHTTPS,
|
||||
baseURL: blobServiceBaseURL,
|
||||
baseURL: serviceBaseURL,
|
||||
apiVersion: apiVersion,
|
||||
sasClient: false,
|
||||
UseSharedKeyLite: false,
|
||||
Sender: &DefaultSender{
|
||||
RetryAttempts: 5,
|
||||
ValidStatusCodes: []int{
|
||||
http.StatusRequestTimeout, // 408
|
||||
http.StatusInternalServerError, // 500
|
||||
http.StatusBadGateway, // 502
|
||||
http.StatusServiceUnavailable, // 503
|
||||
http.StatusGatewayTimeout, // 504
|
||||
},
|
||||
RetryDuration: time.Second * 5,
|
||||
RetryAttempts: defaultRetryAttempts,
|
||||
ValidStatusCodes: defaultValidStatusCodes,
|
||||
RetryDuration: defaultRetryDuration,
|
||||
},
|
||||
}
|
||||
c.userAgent = c.getDefaultUserAgent()
|
||||
|
|
@ -251,6 +332,84 @@ func IsValidStorageAccount(account string) bool {
|
|||
return validStorageAccount.MatchString(account)
|
||||
}
|
||||
|
||||
// NewAccountSASClient contructs a client that uses accountSAS authorization
|
||||
// for its operations.
|
||||
func NewAccountSASClient(account string, token url.Values, env azure.Environment) Client {
|
||||
c := newSASClient()
|
||||
c.accountSASToken = token
|
||||
c.accountName = account
|
||||
c.baseURL = env.StorageEndpointSuffix
|
||||
|
||||
// Get API version and protocol from token
|
||||
c.apiVersion = token.Get("sv")
|
||||
c.useHTTPS = token.Get("spr") == "https"
|
||||
return c
|
||||
}
|
||||
|
||||
// NewAccountSASClientFromEndpointToken constructs a client that uses accountSAS authorization
|
||||
// for its operations using the specified endpoint and SAS token.
|
||||
func NewAccountSASClientFromEndpointToken(endpoint string, sasToken string) (Client, error) {
|
||||
u, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
return Client{}, err
|
||||
}
|
||||
|
||||
token, err := url.ParseQuery(sasToken)
|
||||
if err != nil {
|
||||
return Client{}, err
|
||||
}
|
||||
|
||||
// the host name will look something like this
|
||||
// - foo.blob.core.windows.net
|
||||
// "foo" is the account name
|
||||
// "core.windows.net" is the baseURL
|
||||
|
||||
// find the first dot to get account name
|
||||
i1 := strings.IndexByte(u.Host, '.')
|
||||
if i1 < 0 {
|
||||
return Client{}, fmt.Errorf("failed to find '.' in %s", u.Host)
|
||||
}
|
||||
|
||||
// now find the second dot to get the base URL
|
||||
i2 := strings.IndexByte(u.Host[i1+1:], '.')
|
||||
if i2 < 0 {
|
||||
return Client{}, fmt.Errorf("failed to find '.' in %s", u.Host[i1+1:])
|
||||
}
|
||||
|
||||
c := newSASClient()
|
||||
c.accountSASToken = token
|
||||
c.accountName = u.Host[:i1]
|
||||
c.baseURL = u.Host[i1+i2+2:]
|
||||
|
||||
// Get API version and protocol from token
|
||||
c.apiVersion = token.Get("sv")
|
||||
c.useHTTPS = token.Get("spr") == "https"
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func newSASClient() Client {
|
||||
c := Client{
|
||||
HTTPClient: http.DefaultClient,
|
||||
apiVersion: DefaultAPIVersion,
|
||||
sasClient: true,
|
||||
Sender: &DefaultSender{
|
||||
RetryAttempts: defaultRetryAttempts,
|
||||
ValidStatusCodes: defaultValidStatusCodes,
|
||||
RetryDuration: defaultRetryDuration,
|
||||
},
|
||||
}
|
||||
c.userAgent = c.getDefaultUserAgent()
|
||||
return c
|
||||
}
|
||||
|
||||
func (c Client) isServiceSASClient() bool {
|
||||
return c.sasClient && c.accountSASToken == nil
|
||||
}
|
||||
|
||||
func (c Client) isAccountSASClient() bool {
|
||||
return c.sasClient && c.accountSASToken != nil
|
||||
}
|
||||
|
||||
func (c Client) getDefaultUserAgent() string {
|
||||
return fmt.Sprintf("Go/%s (%s-%s) azure-storage-go/%s api-version/%s",
|
||||
runtime.Version(),
|
||||
|
|
@ -323,6 +482,164 @@ func (c Client) getEndpoint(service, path string, params url.Values) string {
|
|||
return u.String()
|
||||
}
|
||||
|
||||
// AccountSASTokenOptions includes options for constructing
|
||||
// an account SAS token.
|
||||
// https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-an-account-sas
|
||||
type AccountSASTokenOptions struct {
|
||||
APIVersion string
|
||||
Services Services
|
||||
ResourceTypes ResourceTypes
|
||||
Permissions Permissions
|
||||
Start time.Time
|
||||
Expiry time.Time
|
||||
IP string
|
||||
UseHTTPS bool
|
||||
}
|
||||
|
||||
// Services specify services accessible with an account SAS.
|
||||
type Services struct {
|
||||
Blob bool
|
||||
Queue bool
|
||||
Table bool
|
||||
File bool
|
||||
}
|
||||
|
||||
// ResourceTypes specify the resources accesible with an
|
||||
// account SAS.
|
||||
type ResourceTypes struct {
|
||||
Service bool
|
||||
Container bool
|
||||
Object bool
|
||||
}
|
||||
|
||||
// Permissions specifies permissions for an accountSAS.
|
||||
type Permissions struct {
|
||||
Read bool
|
||||
Write bool
|
||||
Delete bool
|
||||
List bool
|
||||
Add bool
|
||||
Create bool
|
||||
Update bool
|
||||
Process bool
|
||||
}
|
||||
|
||||
// GetAccountSASToken creates an account SAS token
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-an-account-sas
|
||||
func (c Client) GetAccountSASToken(options AccountSASTokenOptions) (url.Values, error) {
|
||||
if options.APIVersion == "" {
|
||||
options.APIVersion = c.apiVersion
|
||||
}
|
||||
|
||||
if options.APIVersion < "2015-04-05" {
|
||||
return url.Values{}, fmt.Errorf("account SAS does not support API versions prior to 2015-04-05. API version : %s", options.APIVersion)
|
||||
}
|
||||
|
||||
// build services string
|
||||
services := ""
|
||||
if options.Services.Blob {
|
||||
services += "b"
|
||||
}
|
||||
if options.Services.Queue {
|
||||
services += "q"
|
||||
}
|
||||
if options.Services.Table {
|
||||
services += "t"
|
||||
}
|
||||
if options.Services.File {
|
||||
services += "f"
|
||||
}
|
||||
|
||||
// build resources string
|
||||
resources := ""
|
||||
if options.ResourceTypes.Service {
|
||||
resources += "s"
|
||||
}
|
||||
if options.ResourceTypes.Container {
|
||||
resources += "c"
|
||||
}
|
||||
if options.ResourceTypes.Object {
|
||||
resources += "o"
|
||||
}
|
||||
|
||||
// build permissions string
|
||||
permissions := ""
|
||||
if options.Permissions.Read {
|
||||
permissions += "r"
|
||||
}
|
||||
if options.Permissions.Write {
|
||||
permissions += "w"
|
||||
}
|
||||
if options.Permissions.Delete {
|
||||
permissions += "d"
|
||||
}
|
||||
if options.Permissions.List {
|
||||
permissions += "l"
|
||||
}
|
||||
if options.Permissions.Add {
|
||||
permissions += "a"
|
||||
}
|
||||
if options.Permissions.Create {
|
||||
permissions += "c"
|
||||
}
|
||||
if options.Permissions.Update {
|
||||
permissions += "u"
|
||||
}
|
||||
if options.Permissions.Process {
|
||||
permissions += "p"
|
||||
}
|
||||
|
||||
// build start time, if exists
|
||||
start := ""
|
||||
if options.Start != (time.Time{}) {
|
||||
start = options.Start.Format(time.RFC3339)
|
||||
// For some reason I don't understand, it fails when the rest of the string is included
|
||||
start = start[:10]
|
||||
}
|
||||
|
||||
// build expiry time
|
||||
expiry := options.Expiry.Format(time.RFC3339)
|
||||
// For some reason I don't understand, it fails when the rest of the string is included
|
||||
expiry = expiry[:10]
|
||||
|
||||
protocol := "https,http"
|
||||
if options.UseHTTPS {
|
||||
protocol = "https"
|
||||
}
|
||||
|
||||
stringToSign := strings.Join([]string{
|
||||
c.accountName,
|
||||
permissions,
|
||||
services,
|
||||
resources,
|
||||
start,
|
||||
expiry,
|
||||
options.IP,
|
||||
protocol,
|
||||
options.APIVersion,
|
||||
"",
|
||||
}, "\n")
|
||||
signature := c.computeHmac256(stringToSign)
|
||||
|
||||
sasParams := url.Values{
|
||||
"sv": {options.APIVersion},
|
||||
"ss": {services},
|
||||
"srt": {resources},
|
||||
"sp": {permissions},
|
||||
"se": {expiry},
|
||||
"spr": {protocol},
|
||||
"sig": {signature},
|
||||
}
|
||||
if start != "" {
|
||||
sasParams.Add("st", start)
|
||||
}
|
||||
if options.IP != "" {
|
||||
sasParams.Add("sip", options.IP)
|
||||
}
|
||||
|
||||
return sasParams, nil
|
||||
}
|
||||
|
||||
// GetBlobService returns a BlobStorageClient which can operate on the blob
|
||||
// service of the storage account.
|
||||
func (c Client) GetBlobService() BlobStorageClient {
|
||||
|
|
@ -398,12 +715,13 @@ func (c Client) exec(verb, url string, headers map[string]string, body io.Reader
|
|||
return nil, errors.New("azure/storage: error creating request: " + err.Error())
|
||||
}
|
||||
|
||||
// if a body was provided ensure that the content length was set.
|
||||
// http.NewRequest() will automatically do this for a handful of types
|
||||
// and for those that it doesn't we will handle here.
|
||||
if body != nil && req.ContentLength < 1 {
|
||||
if lr, ok := body.(*io.LimitedReader); ok {
|
||||
setContentLengthFromLimitedReader(req, lr)
|
||||
// http.NewRequest() will automatically set req.ContentLength for a handful of types
|
||||
// otherwise we will handle here.
|
||||
if req.ContentLength < 1 {
|
||||
if clstr, ok := headers["Content-Length"]; ok {
|
||||
if cl, err := strconv.ParseInt(clstr, 10, 64); err == nil {
|
||||
req.ContentLength = cl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -411,6 +729,13 @@ func (c Client) exec(verb, url string, headers map[string]string, body io.Reader
|
|||
req.Header[k] = append(req.Header[k], v) // Must bypass case munging present in `Add` by using map functions directly. See https://github.com/Azure/azure-sdk-for-go/issues/645
|
||||
}
|
||||
|
||||
if c.isAccountSASClient() {
|
||||
// append the SAS token to the query params
|
||||
v := req.URL.Query()
|
||||
v = mergeParams(v, c.accountSASToken)
|
||||
req.URL.RawQuery = v.Encode()
|
||||
}
|
||||
|
||||
resp, err := c.Sender.Send(&c, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
38
vendor/github.com/Azure/azure-sdk-for-go/storage/commonsasuri.go
generated
vendored
Normal file
38
vendor/github.com/Azure/azure-sdk-for-go/storage/commonsasuri.go
generated
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SASOptions includes options used by SAS URIs for different
|
||||
// services and resources.
|
||||
type SASOptions struct {
|
||||
APIVersion string
|
||||
Start time.Time
|
||||
Expiry time.Time
|
||||
IP string
|
||||
UseHTTPS bool
|
||||
Identifier string
|
||||
}
|
||||
|
||||
func addQueryParameter(query url.Values, key, value string) url.Values {
|
||||
if value != "" {
|
||||
query.Add(key, value)
|
||||
}
|
||||
return query
|
||||
}
|
||||
169
vendor/github.com/Azure/azure-sdk-for-go/storage/container.go
generated
vendored
169
vendor/github.com/Azure/azure-sdk-for-go/storage/container.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
|
|
@ -18,12 +32,66 @@ type Container struct {
|
|||
Name string `xml:"Name"`
|
||||
Properties ContainerProperties `xml:"Properties"`
|
||||
Metadata map[string]string
|
||||
sasuri url.URL
|
||||
}
|
||||
|
||||
// Client returns the HTTP client used by the Container reference.
|
||||
func (c *Container) Client() *Client {
|
||||
return &c.bsc.client
|
||||
}
|
||||
|
||||
func (c *Container) buildPath() string {
|
||||
return fmt.Sprintf("/%s", c.Name)
|
||||
}
|
||||
|
||||
// GetURL gets the canonical URL to the container.
|
||||
// This method does not create a publicly accessible URL if the container
|
||||
// is private and this method does not check if the blob exists.
|
||||
func (c *Container) GetURL() string {
|
||||
container := c.Name
|
||||
if container == "" {
|
||||
container = "$root"
|
||||
}
|
||||
return c.bsc.client.getEndpoint(blobServiceName, pathForResource(container, ""), nil)
|
||||
}
|
||||
|
||||
// ContainerSASOptions are options to construct a container SAS
|
||||
// URI.
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas
|
||||
type ContainerSASOptions struct {
|
||||
ContainerSASPermissions
|
||||
OverrideHeaders
|
||||
SASOptions
|
||||
}
|
||||
|
||||
// ContainerSASPermissions includes the available permissions for
|
||||
// a container SAS URI.
|
||||
type ContainerSASPermissions struct {
|
||||
BlobServiceSASPermissions
|
||||
List bool
|
||||
}
|
||||
|
||||
// GetSASURI creates an URL to the container which contains the Shared
|
||||
// Access Signature with the specified options.
|
||||
//
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas
|
||||
func (c *Container) GetSASURI(options ContainerSASOptions) (string, error) {
|
||||
uri := c.GetURL()
|
||||
signedResource := "c"
|
||||
canonicalizedResource, err := c.bsc.client.buildCanonicalizedResource(uri, c.bsc.auth, true)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// build permissions string
|
||||
permissions := options.BlobServiceSASPermissions.buildString()
|
||||
if options.List {
|
||||
permissions += "l"
|
||||
}
|
||||
|
||||
return c.bsc.client.blobAndFileSASURI(options.SASOptions, uri, permissions, canonicalizedResource, signedResource, options.OverrideHeaders)
|
||||
}
|
||||
|
||||
// ContainerProperties contains various properties of a container returned from
|
||||
// various endpoints like ListContainers.
|
||||
type ContainerProperties struct {
|
||||
|
|
@ -224,7 +292,17 @@ func (c *Container) create(options *CreateContainerOptions) (*storageResponse, e
|
|||
// Exists returns true if a container with given name exists
|
||||
// on the storage account, otherwise returns false.
|
||||
func (c *Container) Exists() (bool, error) {
|
||||
uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), url.Values{"restype": {"container"}})
|
||||
q := url.Values{"restype": {"container"}}
|
||||
var uri string
|
||||
if c.bsc.client.isServiceSASClient() {
|
||||
q = mergeParams(q, c.sasuri.Query())
|
||||
newURI := c.sasuri
|
||||
newURI.RawQuery = q.Encode()
|
||||
uri = newURI.String()
|
||||
|
||||
} else {
|
||||
uri = c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), q)
|
||||
}
|
||||
headers := c.bsc.client.getStandardHeaders()
|
||||
|
||||
resp, err := c.bsc.client.exec(http.MethodHead, uri, headers, nil, c.bsc.auth)
|
||||
|
|
@ -399,9 +477,17 @@ func (c *Container) delete(options *DeleteContainerOptions) (*storageResponse, e
|
|||
func (c *Container) ListBlobs(params ListBlobsParameters) (BlobListResponse, error) {
|
||||
q := mergeParams(params.getParameters(), url.Values{
|
||||
"restype": {"container"},
|
||||
"comp": {"list"}},
|
||||
)
|
||||
uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), q)
|
||||
"comp": {"list"},
|
||||
})
|
||||
var uri string
|
||||
if c.bsc.client.isServiceSASClient() {
|
||||
q = mergeParams(q, c.sasuri.Query())
|
||||
newURI := c.sasuri
|
||||
newURI.RawQuery = q.Encode()
|
||||
uri = newURI.String()
|
||||
} else {
|
||||
uri = c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), q)
|
||||
}
|
||||
|
||||
headers := c.bsc.client.getStandardHeaders()
|
||||
headers = addToHeaders(headers, "x-ms-client-request-id", params.RequestID)
|
||||
|
|
@ -420,6 +506,81 @@ func (c *Container) ListBlobs(params ListBlobsParameters) (BlobListResponse, err
|
|||
return out, err
|
||||
}
|
||||
|
||||
// ContainerMetadataOptions includes options for container metadata operations
|
||||
type ContainerMetadataOptions struct {
|
||||
Timeout uint
|
||||
LeaseID string `header:"x-ms-lease-id"`
|
||||
RequestID string `header:"x-ms-client-request-id"`
|
||||
}
|
||||
|
||||
// SetMetadata replaces the metadata for the specified container.
|
||||
//
|
||||
// Some keys may be converted to Camel-Case before sending. All keys
|
||||
// are returned in lower case by GetBlobMetadata. HTTP header names
|
||||
// are case-insensitive so case munging should not matter to other
|
||||
// applications either.
|
||||
//
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/set-container-metadata
|
||||
func (c *Container) SetMetadata(options *ContainerMetadataOptions) error {
|
||||
params := url.Values{
|
||||
"comp": {"metadata"},
|
||||
"restype": {"container"},
|
||||
}
|
||||
headers := c.bsc.client.getStandardHeaders()
|
||||
headers = c.bsc.client.addMetadataToHeaders(headers, c.Metadata)
|
||||
|
||||
if options != nil {
|
||||
params = addTimeout(params, options.Timeout)
|
||||
headers = mergeHeaders(headers, headersFromStruct(*options))
|
||||
}
|
||||
|
||||
uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), params)
|
||||
|
||||
resp, err := c.bsc.client.exec(http.MethodPut, uri, headers, nil, c.bsc.auth)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusOK})
|
||||
}
|
||||
|
||||
// GetMetadata returns all user-defined metadata for the specified container.
|
||||
//
|
||||
// All metadata keys will be returned in lower case. (HTTP header
|
||||
// names are case-insensitive.)
|
||||
//
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/get-container-metadata
|
||||
func (c *Container) GetMetadata(options *ContainerMetadataOptions) error {
|
||||
params := url.Values{
|
||||
"comp": {"metadata"},
|
||||
"restype": {"container"},
|
||||
}
|
||||
headers := c.bsc.client.getStandardHeaders()
|
||||
|
||||
if options != nil {
|
||||
params = addTimeout(params, options.Timeout)
|
||||
headers = mergeHeaders(headers, headersFromStruct(*options))
|
||||
}
|
||||
|
||||
uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), params)
|
||||
|
||||
resp, err := c.bsc.client.exec(http.MethodGet, uri, headers, nil, c.bsc.auth)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.writeMetadata(resp.headers)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Container) writeMetadata(h http.Header) {
|
||||
c.Metadata = writeMetadata(h)
|
||||
}
|
||||
|
||||
func generateContainerACLpayload(policies []ContainerAccessPolicy) (io.Reader, int, error) {
|
||||
sil := SignedIdentifiers{
|
||||
SignedIdentifiers: []SignedIdentifier{},
|
||||
|
|
|
|||
14
vendor/github.com/Azure/azure-sdk-for-go/storage/copyblob.go
generated
vendored
14
vendor/github.com/Azure/azure-sdk-for-go/storage/copyblob.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
|
|
|||
14
vendor/github.com/Azure/azure-sdk-for-go/storage/directory.go
generated
vendored
14
vendor/github.com/Azure/azure-sdk-for-go/storage/directory.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"net/http"
|
||||
|
|
|
|||
16
vendor/github.com/Azure/azure-sdk-for-go/storage/entity.go
generated
vendored
16
vendor/github.com/Azure/azure-sdk-for-go/storage/entity.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
|
@ -12,7 +26,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/satori/uuid"
|
||||
"github.com/satori/go.uuid"
|
||||
)
|
||||
|
||||
// Annotating as secure for gas scanning
|
||||
|
|
|
|||
14
vendor/github.com/Azure/azure-sdk-for-go/storage/file.go
generated
vendored
14
vendor/github.com/Azure/azure-sdk-for-go/storage/file.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
|
|
|||
14
vendor/github.com/Azure/azure-sdk-for-go/storage/fileserviceclient.go
generated
vendored
14
vendor/github.com/Azure/azure-sdk-for-go/storage/fileserviceclient.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
|
|
|
|||
14
vendor/github.com/Azure/azure-sdk-for-go/storage/leaseblob.go
generated
vendored
14
vendor/github.com/Azure/azure-sdk-for-go/storage/leaseblob.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
|
|
|||
14
vendor/github.com/Azure/azure-sdk-for-go/storage/message.go
generated
vendored
14
vendor/github.com/Azure/azure-sdk-for-go/storage/message.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
|
|
|
|||
14
vendor/github.com/Azure/azure-sdk-for-go/storage/odata.go
generated
vendored
14
vendor/github.com/Azure/azure-sdk-for-go/storage/odata.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
// MetadataLevel determines if operations should return a paylod,
|
||||
// and it level of detail.
|
||||
type MetadataLevel string
|
||||
|
|
|
|||
23
vendor/github.com/Azure/azure-sdk-for-go/storage/pageblob.go
generated
vendored
23
vendor/github.com/Azure/azure-sdk-for-go/storage/pageblob.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
|
|
@ -73,10 +87,10 @@ func (b *Blob) modifyRange(blobRange BlobRange, bytes io.Reader, options *PutPag
|
|||
return errors.New("the value for rangeEnd must be greater than or equal to rangeStart")
|
||||
}
|
||||
if blobRange.Start%512 != 0 {
|
||||
return errors.New("the value for rangeStart must be a modulus of 512")
|
||||
return errors.New("the value for rangeStart must be a multiple of 512")
|
||||
}
|
||||
if blobRange.End%512 != 511 {
|
||||
return errors.New("the value for rangeEnd must be a modulus of 511")
|
||||
return errors.New("the value for rangeEnd must be a multiple of 512 - 1")
|
||||
}
|
||||
|
||||
params := url.Values{"comp": {"page"}}
|
||||
|
|
@ -133,7 +147,7 @@ func (b *Blob) GetPageRanges(options *GetPageRangesOptions) (GetPageRangesRespon
|
|||
params = addTimeout(params, options.Timeout)
|
||||
params = addSnapshot(params, options.Snapshot)
|
||||
if options.PreviousSnapshot != nil {
|
||||
params.Add("prevsnapshot", timeRfc1123Formatted(*options.PreviousSnapshot))
|
||||
params.Add("prevsnapshot", timeRFC3339Formatted(*options.PreviousSnapshot))
|
||||
}
|
||||
if options.Range != nil {
|
||||
headers["Range"] = options.Range.String()
|
||||
|
|
@ -186,6 +200,5 @@ func (b *Blob) PutPageBlob(options *PutBlobOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusCreated})
|
||||
return b.respondCreation(resp, BlobTypePage)
|
||||
}
|
||||
|
|
|
|||
14
vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go
generated
vendored
14
vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
|
|
|
|||
146
vendor/github.com/Azure/azure-sdk-for-go/storage/queuesasuri.go
generated
vendored
Normal file
146
vendor/github.com/Azure/azure-sdk-for-go/storage/queuesasuri.go
generated
vendored
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// QueueSASOptions are options to construct a blob SAS
|
||||
// URI.
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas
|
||||
type QueueSASOptions struct {
|
||||
QueueSASPermissions
|
||||
SASOptions
|
||||
}
|
||||
|
||||
// QueueSASPermissions includes the available permissions for
|
||||
// a queue SAS URI.
|
||||
type QueueSASPermissions struct {
|
||||
Read bool
|
||||
Add bool
|
||||
Update bool
|
||||
Process bool
|
||||
}
|
||||
|
||||
func (q QueueSASPermissions) buildString() string {
|
||||
permissions := ""
|
||||
|
||||
if q.Read {
|
||||
permissions += "r"
|
||||
}
|
||||
if q.Add {
|
||||
permissions += "a"
|
||||
}
|
||||
if q.Update {
|
||||
permissions += "u"
|
||||
}
|
||||
if q.Process {
|
||||
permissions += "p"
|
||||
}
|
||||
return permissions
|
||||
}
|
||||
|
||||
// GetSASURI creates an URL to the specified queue which contains the Shared
|
||||
// Access Signature with specified permissions and expiration time.
|
||||
//
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas
|
||||
func (q *Queue) GetSASURI(options QueueSASOptions) (string, error) {
|
||||
canonicalizedResource, err := q.qsc.client.buildCanonicalizedResource(q.buildPath(), q.qsc.auth, true)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// "The canonicalizedresouce portion of the string is a canonical path to the signed resource.
|
||||
// It must include the service name (blob, table, queue or file) for version 2015-02-21 or
|
||||
// later, the storage account name, and the resource name, and must be URL-decoded.
|
||||
// -- https://msdn.microsoft.com/en-us/library/azure/dn140255.aspx
|
||||
// We need to replace + with %2b first to avoid being treated as a space (which is correct for query strings, but not the path component).
|
||||
canonicalizedResource = strings.Replace(canonicalizedResource, "+", "%2b", -1)
|
||||
canonicalizedResource, err = url.QueryUnescape(canonicalizedResource)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
signedStart := ""
|
||||
if options.Start != (time.Time{}) {
|
||||
signedStart = options.Start.UTC().Format(time.RFC3339)
|
||||
}
|
||||
signedExpiry := options.Expiry.UTC().Format(time.RFC3339)
|
||||
|
||||
protocols := "https,http"
|
||||
if options.UseHTTPS {
|
||||
protocols = "https"
|
||||
}
|
||||
|
||||
permissions := options.QueueSASPermissions.buildString()
|
||||
stringToSign, err := queueSASStringToSign(q.qsc.client.apiVersion, canonicalizedResource, signedStart, signedExpiry, options.IP, permissions, protocols, options.Identifier)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
sig := q.qsc.client.computeHmac256(stringToSign)
|
||||
sasParams := url.Values{
|
||||
"sv": {q.qsc.client.apiVersion},
|
||||
"se": {signedExpiry},
|
||||
"sp": {permissions},
|
||||
"sig": {sig},
|
||||
}
|
||||
|
||||
if q.qsc.client.apiVersion >= "2015-04-05" {
|
||||
sasParams.Add("spr", protocols)
|
||||
addQueryParameter(sasParams, "sip", options.IP)
|
||||
}
|
||||
|
||||
uri := q.qsc.client.getEndpoint(queueServiceName, q.buildPath(), nil)
|
||||
sasURL, err := url.Parse(uri)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
sasURL.RawQuery = sasParams.Encode()
|
||||
return sasURL.String(), nil
|
||||
}
|
||||
|
||||
func queueSASStringToSign(signedVersion, canonicalizedResource, signedStart, signedExpiry, signedIP, signedPermissions, protocols, signedIdentifier string) (string, error) {
|
||||
|
||||
if signedVersion >= "2015-02-21" {
|
||||
canonicalizedResource = "/queue" + canonicalizedResource
|
||||
}
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/azure/dn140255.aspx#Anchor_12
|
||||
if signedVersion >= "2015-04-05" {
|
||||
return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s",
|
||||
signedPermissions,
|
||||
signedStart,
|
||||
signedExpiry,
|
||||
canonicalizedResource,
|
||||
signedIdentifier,
|
||||
signedIP,
|
||||
protocols,
|
||||
signedVersion), nil
|
||||
|
||||
}
|
||||
|
||||
// reference: http://msdn.microsoft.com/en-us/library/azure/dn140255.aspx
|
||||
if signedVersion >= "2013-08-15" {
|
||||
return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s", signedPermissions, signedStart, signedExpiry, canonicalizedResource, signedIdentifier, signedVersion), nil
|
||||
}
|
||||
|
||||
return "", errors.New("storage: not implemented SAS for versions earlier than 2013-08-15")
|
||||
}
|
||||
14
vendor/github.com/Azure/azure-sdk-for-go/storage/queueserviceclient.go
generated
vendored
14
vendor/github.com/Azure/azure-sdk-for-go/storage/queueserviceclient.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
// QueueServiceClient contains operations for Microsoft Azure Queue Storage
|
||||
// Service.
|
||||
type QueueServiceClient struct {
|
||||
|
|
|
|||
14
vendor/github.com/Azure/azure-sdk-for-go/storage/share.go
generated
vendored
14
vendor/github.com/Azure/azure-sdk-for-go/storage/share.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
|
|
|||
14
vendor/github.com/Azure/azure-sdk-for-go/storage/storagepolicy.go
generated
vendored
14
vendor/github.com/Azure/azure-sdk-for-go/storage/storagepolicy.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
|
|
|||
14
vendor/github.com/Azure/azure-sdk-for-go/storage/storageservice.go
generated
vendored
14
vendor/github.com/Azure/azure-sdk-for-go/storage/storageservice.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
|
|
|||
25
vendor/github.com/Azure/azure-sdk-for-go/storage/table.go
generated
vendored
25
vendor/github.com/Azure/azure-sdk-for-go/storage/table.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
|
@ -174,11 +188,7 @@ func (t *Table) Delete(timeout uint, options *TableOptions) error {
|
|||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
|
||||
if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil {
|
||||
return err
|
||||
|
||||
}
|
||||
return nil
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusNoContent})
|
||||
}
|
||||
|
||||
// QueryOptions includes options for a query entities operation.
|
||||
|
|
@ -261,10 +271,7 @@ func (t *Table) SetPermissions(tap []TableAccessPolicy, timeout uint, options *T
|
|||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
|
||||
if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusNoContent})
|
||||
}
|
||||
|
||||
func generateTableACLPayload(policies []TableAccessPolicy) (io.Reader, int, error) {
|
||||
|
|
|
|||
32
vendor/github.com/Azure/azure-sdk-for-go/storage/table_batch.go
generated
vendored
32
vendor/github.com/Azure/azure-sdk-for-go/storage/table_batch.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
|
@ -12,7 +26,7 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/satori/uuid"
|
||||
"github.com/marstr/guid"
|
||||
)
|
||||
|
||||
// Operation type. Insert, Delete, Replace etc.
|
||||
|
|
@ -117,14 +131,26 @@ func (t *TableBatch) MergeEntity(entity *Entity) {
|
|||
// the changesets.
|
||||
// As per document https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/performing-entity-group-transactions
|
||||
func (t *TableBatch) ExecuteBatch() error {
|
||||
changesetBoundary := fmt.Sprintf("changeset_%s", uuid.NewV1())
|
||||
|
||||
// Using `github.com/marstr/guid` is in response to issue #947 (https://github.com/Azure/azure-sdk-for-go/issues/947).
|
||||
id, err := guid.NewGUIDs(guid.CreationStrategyVersion1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
changesetBoundary := fmt.Sprintf("changeset_%s", id.String())
|
||||
uri := t.Table.tsc.client.getEndpoint(tableServiceName, "$batch", nil)
|
||||
changesetBody, err := t.generateChangesetBody(changesetBoundary)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
boundary := fmt.Sprintf("batch_%s", uuid.NewV1())
|
||||
id, err = guid.NewGUIDs(guid.CreationStrategyVersion1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
boundary := fmt.Sprintf("batch_%s", id.String())
|
||||
body, err := generateBody(changesetBody, changesetBoundary, boundary)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
14
vendor/github.com/Azure/azure-sdk-for-go/storage/tableserviceclient.go
generated
vendored
14
vendor/github.com/Azure/azure-sdk-for-go/storage/tableserviceclient.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
|
|
|||
44
vendor/github.com/Azure/azure-sdk-for-go/storage/util.go
generated
vendored
44
vendor/github.com/Azure/azure-sdk-for-go/storage/util.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/hmac"
|
||||
|
|
@ -18,7 +32,29 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
fixedTime = time.Date(2050, time.December, 20, 21, 55, 0, 0, time.FixedZone("GMT", -6))
|
||||
fixedTime = time.Date(2050, time.December, 20, 21, 55, 0, 0, time.FixedZone("GMT", -6))
|
||||
accountSASOptions = AccountSASTokenOptions{
|
||||
Services: Services{
|
||||
Blob: true,
|
||||
},
|
||||
ResourceTypes: ResourceTypes{
|
||||
Service: true,
|
||||
Container: true,
|
||||
Object: true,
|
||||
},
|
||||
Permissions: Permissions{
|
||||
Read: true,
|
||||
Write: true,
|
||||
Delete: true,
|
||||
List: true,
|
||||
Add: true,
|
||||
Create: true,
|
||||
Update: true,
|
||||
Process: true,
|
||||
},
|
||||
Expiry: fixedTime,
|
||||
UseHTTPS: true,
|
||||
}
|
||||
)
|
||||
|
||||
func (c Client) computeHmac256(message string) string {
|
||||
|
|
@ -35,6 +71,10 @@ func timeRfc1123Formatted(t time.Time) string {
|
|||
return t.Format(http.TimeFormat)
|
||||
}
|
||||
|
||||
func timeRFC3339Formatted(t time.Time) string {
|
||||
return t.Format("2006-01-02T15:04:05.0000000Z")
|
||||
}
|
||||
|
||||
func mergeParams(v1, v2 url.Values) url.Values {
|
||||
out := url.Values{}
|
||||
for k, v := range v1 {
|
||||
|
|
@ -136,7 +176,7 @@ func addTimeout(params url.Values, timeout uint) url.Values {
|
|||
|
||||
func addSnapshot(params url.Values, snapshot *time.Time) url.Values {
|
||||
if snapshot != nil {
|
||||
params.Add("snapshot", snapshot.Format("2006-01-02T15:04:05.0000000Z"))
|
||||
params.Add("snapshot", timeRFC3339Formatted(*snapshot))
|
||||
}
|
||||
return params
|
||||
}
|
||||
|
|
|
|||
12
vendor/github.com/Azure/azure-sdk-for-go/storage/util_1.7.go
generated
vendored
12
vendor/github.com/Azure/azure-sdk-for-go/storage/util_1.7.go
generated
vendored
|
|
@ -1,12 +0,0 @@
|
|||
// +build !go1.8
|
||||
|
||||
package storage
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func setContentLengthFromLimitedReader(req *http.Request, lr *io.LimitedReader) {
|
||||
req.ContentLength = lr.N
|
||||
}
|
||||
18
vendor/github.com/Azure/azure-sdk-for-go/storage/util_1.8.go
generated
vendored
18
vendor/github.com/Azure/azure-sdk-for-go/storage/util_1.8.go
generated
vendored
|
|
@ -1,18 +0,0 @@
|
|||
// +build go1.8
|
||||
|
||||
package storage
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func setContentLengthFromLimitedReader(req *http.Request, lr *io.LimitedReader) {
|
||||
req.ContentLength = lr.N
|
||||
snapshot := *lr
|
||||
req.GetBody = func() (io.ReadCloser, error) {
|
||||
r := snapshot
|
||||
return ioutil.NopCloser(&r), nil
|
||||
}
|
||||
}
|
||||
16
vendor/github.com/Azure/azure-sdk-for-go/storage/version.go
generated
vendored
16
vendor/github.com/Azure/azure-sdk-for-go/storage/version.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
var (
|
||||
sdkVersion = "10.0.2"
|
||||
sdkVersion = "v12.3.0-beta"
|
||||
)
|
||||
|
|
|
|||
34
vendor/github.com/Azure/go-autorest/autorest/adal/README.md
generated
vendored
34
vendor/github.com/Azure/go-autorest/autorest/adal/README.md
generated
vendored
|
|
@ -218,6 +218,40 @@ if (err == nil) {
|
|||
}
|
||||
```
|
||||
|
||||
#### Username password authenticate
|
||||
|
||||
```Go
|
||||
spt, err := adal.NewServicePrincipalTokenFromUsernamePassword(
|
||||
oauthConfig,
|
||||
applicationID,
|
||||
username,
|
||||
password,
|
||||
resource,
|
||||
callbacks...)
|
||||
|
||||
if (err == nil) {
|
||||
token := spt.Token
|
||||
}
|
||||
```
|
||||
|
||||
#### Authorization code authenticate
|
||||
|
||||
``` Go
|
||||
spt, err := adal.NewServicePrincipalTokenFromAuthorizationCode(
|
||||
oauthConfig,
|
||||
applicationID,
|
||||
clientSecret,
|
||||
authorizationCode,
|
||||
redirectURI,
|
||||
resource,
|
||||
callbacks...)
|
||||
|
||||
err = spt.Refresh()
|
||||
if (err == nil) {
|
||||
token := spt.Token
|
||||
}
|
||||
```
|
||||
|
||||
### Command Line Tool
|
||||
|
||||
A command line tool is available in `cmd/adal.go` that can acquire a token for a given resource. It supports all flows mentioned above.
|
||||
|
|
|
|||
30
vendor/github.com/Azure/go-autorest/autorest/adal/config.go
generated
vendored
30
vendor/github.com/Azure/go-autorest/autorest/adal/config.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package adal
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
|
@ -18,8 +32,24 @@ type OAuthConfig struct {
|
|||
DeviceCodeEndpoint url.URL
|
||||
}
|
||||
|
||||
// IsZero returns true if the OAuthConfig object is zero-initialized.
|
||||
func (oac OAuthConfig) IsZero() bool {
|
||||
return oac == OAuthConfig{}
|
||||
}
|
||||
|
||||
func validateStringParam(param, name string) error {
|
||||
if len(param) == 0 {
|
||||
return fmt.Errorf("parameter '" + name + "' cannot be empty")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewOAuthConfig returns an OAuthConfig with tenant specific urls
|
||||
func NewOAuthConfig(activeDirectoryEndpoint, tenantID string) (*OAuthConfig, error) {
|
||||
if err := validateStringParam(activeDirectoryEndpoint, "activeDirectoryEndpoint"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// it's legal for tenantID to be empty so don't validate it
|
||||
const activeDirectoryEndpointTemplate = "%s/oauth2/%s?api-version=%s"
|
||||
u, err := url.Parse(activeDirectoryEndpoint)
|
||||
if err != nil {
|
||||
|
|
|
|||
14
vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package adal
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
/*
|
||||
This file is largely based on rjw57/oauth2device's code, with the follow differences:
|
||||
* scope -> resource, and only allow a single one
|
||||
|
|
|
|||
20
vendor/github.com/Azure/go-autorest/autorest/adal/msi.go
generated
vendored
Normal file
20
vendor/github.com/Azure/go-autorest/autorest/adal/msi.go
generated
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// +build !windows
|
||||
|
||||
package adal
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
// msiPath is the path to the MSI Extension settings file (to discover the endpoint)
|
||||
var msiPath = "/var/lib/waagent/ManagedIdentity-Settings"
|
||||
25
vendor/github.com/Azure/go-autorest/autorest/adal/msi_windows.go
generated
vendored
Normal file
25
vendor/github.com/Azure/go-autorest/autorest/adal/msi_windows.go
generated
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// +build windows
|
||||
|
||||
package adal
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// msiPath is the path to the MSI Extension settings file (to discover the endpoint)
|
||||
var msiPath = strings.Join([]string{os.Getenv("SystemDrive"), "WindowsAzure/Config/ManagedIdentity-Settings"}, "/")
|
||||
14
vendor/github.com/Azure/go-autorest/autorest/adal/persist.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/adal/persist.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package adal
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
|
|
|||
14
vendor/github.com/Azure/go-autorest/autorest/adal/sender.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/adal/sender.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package adal
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
|
|
|||
326
vendor/github.com/Azure/go-autorest/autorest/adal/token.go
generated
vendored
326
vendor/github.com/Azure/go-autorest/autorest/adal/token.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package adal
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
|
|
@ -13,14 +27,15 @@ import (
|
|||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest/date"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultRefresh = 5 * time.Minute
|
||||
tokenBaseDate = "1970-01-01T00:00:00Z"
|
||||
|
||||
// OAuthGrantTypeDeviceCode is the "grant_type" identifier used in device flow
|
||||
OAuthGrantTypeDeviceCode = "device_code"
|
||||
|
|
@ -28,27 +43,30 @@ const (
|
|||
// OAuthGrantTypeClientCredentials is the "grant_type" identifier used in credential flows
|
||||
OAuthGrantTypeClientCredentials = "client_credentials"
|
||||
|
||||
// OAuthGrantTypeUserPass is the "grant_type" identifier used in username and password auth flows
|
||||
OAuthGrantTypeUserPass = "password"
|
||||
|
||||
// OAuthGrantTypeRefreshToken is the "grant_type" identifier used in refresh token flows
|
||||
OAuthGrantTypeRefreshToken = "refresh_token"
|
||||
|
||||
// managedIdentitySettingsPath is the path to the MSI Extension settings file (to discover the endpoint)
|
||||
managedIdentitySettingsPath = "/var/lib/waagent/ManagedIdentity-Settings"
|
||||
// OAuthGrantTypeAuthorizationCode is the "grant_type" identifier used in authorization code flows
|
||||
OAuthGrantTypeAuthorizationCode = "authorization_code"
|
||||
|
||||
// metadataHeader is the header required by MSI extension
|
||||
metadataHeader = "Metadata"
|
||||
)
|
||||
|
||||
var expirationBase time.Time
|
||||
|
||||
func init() {
|
||||
expirationBase, _ = time.Parse(time.RFC3339, tokenBaseDate)
|
||||
}
|
||||
|
||||
// OAuthTokenProvider is an interface which should be implemented by an access token retriever
|
||||
type OAuthTokenProvider interface {
|
||||
OAuthToken() string
|
||||
}
|
||||
|
||||
// TokenRefreshError is an interface used by errors returned during token refresh.
|
||||
type TokenRefreshError interface {
|
||||
error
|
||||
Response() *http.Response
|
||||
}
|
||||
|
||||
// Refresher is an interface for token refresh functionality
|
||||
type Refresher interface {
|
||||
Refresh() error
|
||||
|
|
@ -73,13 +91,21 @@ type Token struct {
|
|||
Type string `json:"token_type"`
|
||||
}
|
||||
|
||||
// IsZero returns true if the token object is zero-initialized.
|
||||
func (t Token) IsZero() bool {
|
||||
return t == Token{}
|
||||
}
|
||||
|
||||
// Expires returns the time.Time when the Token expires.
|
||||
func (t Token) Expires() time.Time {
|
||||
s, err := strconv.Atoi(t.ExpiresOn)
|
||||
if err != nil {
|
||||
s = -3600
|
||||
}
|
||||
return expirationBase.Add(time.Duration(s) * time.Second).UTC()
|
||||
|
||||
expiration := date.NewUnixTimeFromSeconds(float64(s))
|
||||
|
||||
return time.Time(expiration).UTC()
|
||||
}
|
||||
|
||||
// IsExpired returns true if the Token is expired, false otherwise.
|
||||
|
|
@ -137,10 +163,36 @@ type ServicePrincipalCertificateSecret struct {
|
|||
type ServicePrincipalMSISecret struct {
|
||||
}
|
||||
|
||||
// ServicePrincipalUsernamePasswordSecret implements ServicePrincipalSecret for username and password auth.
|
||||
type ServicePrincipalUsernamePasswordSecret struct {
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
// ServicePrincipalAuthorizationCodeSecret implements ServicePrincipalSecret for authorization code auth.
|
||||
type ServicePrincipalAuthorizationCodeSecret struct {
|
||||
ClientSecret string
|
||||
AuthorizationCode string
|
||||
RedirectURI string
|
||||
}
|
||||
|
||||
// SetAuthenticationValues is a method of the interface ServicePrincipalSecret.
|
||||
func (secret *ServicePrincipalAuthorizationCodeSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error {
|
||||
v.Set("code", secret.AuthorizationCode)
|
||||
v.Set("client_secret", secret.ClientSecret)
|
||||
v.Set("redirect_uri", secret.RedirectURI)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetAuthenticationValues is a method of the interface ServicePrincipalSecret.
|
||||
func (secret *ServicePrincipalUsernamePasswordSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error {
|
||||
v.Set("username", secret.Username)
|
||||
v.Set("password", secret.Password)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetAuthenticationValues is a method of the interface ServicePrincipalSecret.
|
||||
// MSI extension requires the authority field to be set to the real tenant authority endpoint
|
||||
func (msiSecret *ServicePrincipalMSISecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error {
|
||||
v.Set("authority", spt.oauthConfig.AuthorityEndpoint.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -193,25 +245,46 @@ func (secret *ServicePrincipalCertificateSecret) SetAuthenticationValues(spt *Se
|
|||
type ServicePrincipalToken struct {
|
||||
Token
|
||||
|
||||
secret ServicePrincipalSecret
|
||||
oauthConfig OAuthConfig
|
||||
clientID string
|
||||
resource string
|
||||
autoRefresh bool
|
||||
refreshWithin time.Duration
|
||||
sender Sender
|
||||
secret ServicePrincipalSecret
|
||||
oauthConfig OAuthConfig
|
||||
clientID string
|
||||
resource string
|
||||
autoRefresh bool
|
||||
autoRefreshLock *sync.Mutex
|
||||
refreshWithin time.Duration
|
||||
sender Sender
|
||||
|
||||
refreshCallbacks []TokenRefreshCallback
|
||||
}
|
||||
|
||||
func validateOAuthConfig(oac OAuthConfig) error {
|
||||
if oac.IsZero() {
|
||||
return fmt.Errorf("parameter 'oauthConfig' cannot be zero-initialized")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenWithSecret create a ServicePrincipalToken using the supplied ServicePrincipalSecret implementation.
|
||||
func NewServicePrincipalTokenWithSecret(oauthConfig OAuthConfig, id string, resource string, secret ServicePrincipalSecret, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateOAuthConfig(oauthConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(id, "id"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if secret == nil {
|
||||
return nil, fmt.Errorf("parameter 'secret' cannot be nil")
|
||||
}
|
||||
spt := &ServicePrincipalToken{
|
||||
oauthConfig: oauthConfig,
|
||||
secret: secret,
|
||||
clientID: id,
|
||||
resource: resource,
|
||||
autoRefresh: true,
|
||||
autoRefreshLock: &sync.Mutex{},
|
||||
refreshWithin: defaultRefresh,
|
||||
sender: &http.Client{},
|
||||
refreshCallbacks: callbacks,
|
||||
|
|
@ -221,6 +294,18 @@ func NewServicePrincipalTokenWithSecret(oauthConfig OAuthConfig, id string, reso
|
|||
|
||||
// NewServicePrincipalTokenFromManualToken creates a ServicePrincipalToken using the supplied token
|
||||
func NewServicePrincipalTokenFromManualToken(oauthConfig OAuthConfig, clientID string, resource string, token Token, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateOAuthConfig(oauthConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(clientID, "clientID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if token.IsZero() {
|
||||
return nil, fmt.Errorf("parameter 'token' cannot be zero-initialized")
|
||||
}
|
||||
spt, err := NewServicePrincipalTokenWithSecret(
|
||||
oauthConfig,
|
||||
clientID,
|
||||
|
|
@ -239,6 +324,18 @@ func NewServicePrincipalTokenFromManualToken(oauthConfig OAuthConfig, clientID s
|
|||
// NewServicePrincipalToken creates a ServicePrincipalToken from the supplied Service Principal
|
||||
// credentials scoped to the named resource.
|
||||
func NewServicePrincipalToken(oauthConfig OAuthConfig, clientID string, secret string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateOAuthConfig(oauthConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(clientID, "clientID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(secret, "secret"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewServicePrincipalTokenWithSecret(
|
||||
oauthConfig,
|
||||
clientID,
|
||||
|
|
@ -250,8 +347,23 @@ func NewServicePrincipalToken(oauthConfig OAuthConfig, clientID string, secret s
|
|||
)
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromCertificate create a ServicePrincipalToken from the supplied pkcs12 bytes.
|
||||
// NewServicePrincipalTokenFromCertificate creates a ServicePrincipalToken from the supplied pkcs12 bytes.
|
||||
func NewServicePrincipalTokenFromCertificate(oauthConfig OAuthConfig, clientID string, certificate *x509.Certificate, privateKey *rsa.PrivateKey, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateOAuthConfig(oauthConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(clientID, "clientID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if certificate == nil {
|
||||
return nil, fmt.Errorf("parameter 'certificate' cannot be nil")
|
||||
}
|
||||
if privateKey == nil {
|
||||
return nil, fmt.Errorf("parameter 'privateKey' cannot be nil")
|
||||
}
|
||||
return NewServicePrincipalTokenWithSecret(
|
||||
oauthConfig,
|
||||
clientID,
|
||||
|
|
@ -264,57 +376,175 @@ func NewServicePrincipalTokenFromCertificate(oauthConfig OAuthConfig, clientID s
|
|||
)
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromMSI creates a ServicePrincipalToken via the MSI VM Extension.
|
||||
func NewServicePrincipalTokenFromMSI(oauthConfig OAuthConfig, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
return newServicePrincipalTokenFromMSI(oauthConfig, resource, managedIdentitySettingsPath, callbacks...)
|
||||
// NewServicePrincipalTokenFromUsernamePassword creates a ServicePrincipalToken from the username and password.
|
||||
func NewServicePrincipalTokenFromUsernamePassword(oauthConfig OAuthConfig, clientID string, username string, password string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateOAuthConfig(oauthConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(clientID, "clientID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(username, "username"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(password, "password"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewServicePrincipalTokenWithSecret(
|
||||
oauthConfig,
|
||||
clientID,
|
||||
resource,
|
||||
&ServicePrincipalUsernamePasswordSecret{
|
||||
Username: username,
|
||||
Password: password,
|
||||
},
|
||||
callbacks...,
|
||||
)
|
||||
}
|
||||
|
||||
func newServicePrincipalTokenFromMSI(oauthConfig OAuthConfig, resource, settingsPath string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
// Read MSI settings
|
||||
bytes, err := ioutil.ReadFile(settingsPath)
|
||||
if err != nil {
|
||||
// NewServicePrincipalTokenFromAuthorizationCode creates a ServicePrincipalToken from the
|
||||
func NewServicePrincipalTokenFromAuthorizationCode(oauthConfig OAuthConfig, clientID string, clientSecret string, authorizationCode string, redirectURI string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
|
||||
if err := validateOAuthConfig(oauthConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(clientID, "clientID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(clientSecret, "clientSecret"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(authorizationCode, "authorizationCode"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(redirectURI, "redirectURI"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewServicePrincipalTokenWithSecret(
|
||||
oauthConfig,
|
||||
clientID,
|
||||
resource,
|
||||
&ServicePrincipalAuthorizationCodeSecret{
|
||||
ClientSecret: clientSecret,
|
||||
AuthorizationCode: authorizationCode,
|
||||
RedirectURI: redirectURI,
|
||||
},
|
||||
callbacks...,
|
||||
)
|
||||
}
|
||||
|
||||
// GetMSIVMEndpoint gets the MSI endpoint on Virtual Machines.
|
||||
func GetMSIVMEndpoint() (string, error) {
|
||||
return getMSIVMEndpoint(msiPath)
|
||||
}
|
||||
|
||||
func getMSIVMEndpoint(path string) (string, error) {
|
||||
// Read MSI settings
|
||||
bytes, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
msiSettings := struct {
|
||||
URL string `json:"url"`
|
||||
}{}
|
||||
err = json.Unmarshal(bytes, &msiSettings)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
return msiSettings.URL, nil
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromMSI creates a ServicePrincipalToken via the MSI VM Extension.
|
||||
// It will use the system assigned identity when creating the token.
|
||||
func NewServicePrincipalTokenFromMSI(msiEndpoint, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
return newServicePrincipalTokenFromMSI(msiEndpoint, resource, nil, callbacks...)
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromMSIWithUserAssignedID creates a ServicePrincipalToken via the MSI VM Extension.
|
||||
// It will use the specified user assigned identity when creating the token.
|
||||
func NewServicePrincipalTokenFromMSIWithUserAssignedID(msiEndpoint, resource string, userAssignedID string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
return newServicePrincipalTokenFromMSI(msiEndpoint, resource, &userAssignedID, callbacks...)
|
||||
}
|
||||
|
||||
func newServicePrincipalTokenFromMSI(msiEndpoint, resource string, userAssignedID *string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateStringParam(msiEndpoint, "msiEndpoint"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if userAssignedID != nil {
|
||||
if err := validateStringParam(*userAssignedID, "userAssignedID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// We set the oauth config token endpoint to be MSI's endpoint
|
||||
// We leave the authority as-is so MSI can POST it with the token request
|
||||
msiEndpointURL, err := url.Parse(msiSettings.URL)
|
||||
msiEndpointURL, err := url.Parse(msiEndpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msiTokenEndpointURL, err := msiEndpointURL.Parse("/oauth2/token")
|
||||
oauthConfig, err := NewOAuthConfig(msiEndpointURL.String(), "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
oauthConfig.TokenEndpoint = *msiTokenEndpointURL
|
||||
|
||||
spt := &ServicePrincipalToken{
|
||||
oauthConfig: oauthConfig,
|
||||
oauthConfig: *oauthConfig,
|
||||
secret: &ServicePrincipalMSISecret{},
|
||||
resource: resource,
|
||||
autoRefresh: true,
|
||||
autoRefreshLock: &sync.Mutex{},
|
||||
refreshWithin: defaultRefresh,
|
||||
sender: &http.Client{},
|
||||
refreshCallbacks: callbacks,
|
||||
}
|
||||
|
||||
if userAssignedID != nil {
|
||||
spt.clientID = *userAssignedID
|
||||
}
|
||||
|
||||
return spt, nil
|
||||
}
|
||||
|
||||
// internal type that implements TokenRefreshError
|
||||
type tokenRefreshError struct {
|
||||
message string
|
||||
resp *http.Response
|
||||
}
|
||||
|
||||
// Error implements the error interface which is part of the TokenRefreshError interface.
|
||||
func (tre tokenRefreshError) Error() string {
|
||||
return tre.message
|
||||
}
|
||||
|
||||
// Response implements the TokenRefreshError interface, it returns the raw HTTP response from the refresh operation.
|
||||
func (tre tokenRefreshError) Response() *http.Response {
|
||||
return tre.resp
|
||||
}
|
||||
|
||||
func newTokenRefreshError(message string, resp *http.Response) TokenRefreshError {
|
||||
return tokenRefreshError{message: message, resp: resp}
|
||||
}
|
||||
|
||||
// EnsureFresh will refresh the token if it will expire within the refresh window (as set by
|
||||
// RefreshWithin) and autoRefresh flag is on.
|
||||
// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use.
|
||||
func (spt *ServicePrincipalToken) EnsureFresh() error {
|
||||
if spt.autoRefresh && spt.WillExpireIn(spt.refreshWithin) {
|
||||
return spt.Refresh()
|
||||
// take the lock then check to see if the token was already refreshed
|
||||
spt.autoRefreshLock.Lock()
|
||||
defer spt.autoRefreshLock.Unlock()
|
||||
if spt.WillExpireIn(spt.refreshWithin) {
|
||||
return spt.Refresh()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -333,15 +563,28 @@ func (spt *ServicePrincipalToken) InvokeRefreshCallbacks(token Token) error {
|
|||
}
|
||||
|
||||
// Refresh obtains a fresh token for the Service Principal.
|
||||
// This method is not safe for concurrent use and should be syncrhonized.
|
||||
func (spt *ServicePrincipalToken) Refresh() error {
|
||||
return spt.refreshInternal(spt.resource)
|
||||
}
|
||||
|
||||
// RefreshExchange refreshes the token, but for a different resource.
|
||||
// This method is not safe for concurrent use and should be syncrhonized.
|
||||
func (spt *ServicePrincipalToken) RefreshExchange(resource string) error {
|
||||
return spt.refreshInternal(resource)
|
||||
}
|
||||
|
||||
func (spt *ServicePrincipalToken) getGrantType() string {
|
||||
switch spt.secret.(type) {
|
||||
case *ServicePrincipalUsernamePasswordSecret:
|
||||
return OAuthGrantTypeUserPass
|
||||
case *ServicePrincipalAuthorizationCodeSecret:
|
||||
return OAuthGrantTypeAuthorizationCode
|
||||
default:
|
||||
return OAuthGrantTypeClientCredentials
|
||||
}
|
||||
}
|
||||
|
||||
func (spt *ServicePrincipalToken) refreshInternal(resource string) error {
|
||||
v := url.Values{}
|
||||
v.Set("client_id", spt.clientID)
|
||||
|
|
@ -351,7 +594,7 @@ func (spt *ServicePrincipalToken) refreshInternal(resource string) error {
|
|||
v.Set("grant_type", OAuthGrantTypeRefreshToken)
|
||||
v.Set("refresh_token", spt.RefreshToken)
|
||||
} else {
|
||||
v.Set("grant_type", OAuthGrantTypeClientCredentials)
|
||||
v.Set("grant_type", spt.getGrantType())
|
||||
err := spt.secret.SetAuthenticationValues(spt, &v)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -374,12 +617,17 @@ func (spt *ServicePrincipalToken) refreshInternal(resource string) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("adal: Failed to execute the refresh request. Error = '%v'", err)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
rb, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("adal: Refresh request failed. Status Code = '%d'", resp.StatusCode)
|
||||
if err != nil {
|
||||
return newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Failed reading response body", resp.StatusCode), resp)
|
||||
}
|
||||
return newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Response body: %s", resp.StatusCode, string(rb)), resp)
|
||||
}
|
||||
|
||||
rb, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("adal: Failed to read a new service principal token during refresh. Error = '%v'", err)
|
||||
}
|
||||
|
|
|
|||
95
vendor/github.com/Azure/go-autorest/autorest/authorization.go
generated
vendored
95
vendor/github.com/Azure/go-autorest/autorest/authorization.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package autorest
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
|
@ -10,9 +24,12 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
bearerChallengeHeader = "Www-Authenticate"
|
||||
bearer = "Bearer"
|
||||
tenantID = "tenantID"
|
||||
bearerChallengeHeader = "Www-Authenticate"
|
||||
bearer = "Bearer"
|
||||
tenantID = "tenantID"
|
||||
apiKeyAuthorizerHeader = "Ocp-Apim-Subscription-Key"
|
||||
bingAPISdkHeader = "X-BingApis-SDK-Client"
|
||||
golangBingAPISdkHeaderValue = "Go-SDK"
|
||||
)
|
||||
|
||||
// Authorizer is the interface that provides a PrepareDecorator used to supply request
|
||||
|
|
@ -30,6 +47,53 @@ func (na NullAuthorizer) WithAuthorization() PrepareDecorator {
|
|||
return WithNothing()
|
||||
}
|
||||
|
||||
// APIKeyAuthorizer implements API Key authorization.
|
||||
type APIKeyAuthorizer struct {
|
||||
headers map[string]interface{}
|
||||
queryParameters map[string]interface{}
|
||||
}
|
||||
|
||||
// NewAPIKeyAuthorizerWithHeaders creates an ApiKeyAuthorizer with headers.
|
||||
func NewAPIKeyAuthorizerWithHeaders(headers map[string]interface{}) *APIKeyAuthorizer {
|
||||
return NewAPIKeyAuthorizer(headers, nil)
|
||||
}
|
||||
|
||||
// NewAPIKeyAuthorizerWithQueryParameters creates an ApiKeyAuthorizer with query parameters.
|
||||
func NewAPIKeyAuthorizerWithQueryParameters(queryParameters map[string]interface{}) *APIKeyAuthorizer {
|
||||
return NewAPIKeyAuthorizer(nil, queryParameters)
|
||||
}
|
||||
|
||||
// NewAPIKeyAuthorizer creates an ApiKeyAuthorizer with headers.
|
||||
func NewAPIKeyAuthorizer(headers map[string]interface{}, queryParameters map[string]interface{}) *APIKeyAuthorizer {
|
||||
return &APIKeyAuthorizer{headers: headers, queryParameters: queryParameters}
|
||||
}
|
||||
|
||||
// WithAuthorization returns a PrepareDecorator that adds an HTTP headers and Query Paramaters
|
||||
func (aka *APIKeyAuthorizer) WithAuthorization() PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return DecoratePreparer(p, WithHeaders(aka.headers), WithQueryParameters(aka.queryParameters))
|
||||
}
|
||||
}
|
||||
|
||||
// CognitiveServicesAuthorizer implements authorization for Cognitive Services.
|
||||
type CognitiveServicesAuthorizer struct {
|
||||
subscriptionKey string
|
||||
}
|
||||
|
||||
// NewCognitiveServicesAuthorizer is
|
||||
func NewCognitiveServicesAuthorizer(subscriptionKey string) *CognitiveServicesAuthorizer {
|
||||
return &CognitiveServicesAuthorizer{subscriptionKey: subscriptionKey}
|
||||
}
|
||||
|
||||
// WithAuthorization is
|
||||
func (csa *CognitiveServicesAuthorizer) WithAuthorization() PrepareDecorator {
|
||||
headers := make(map[string]interface{})
|
||||
headers[apiKeyAuthorizerHeader] = csa.subscriptionKey
|
||||
headers[bingAPISdkHeader] = golangBingAPISdkHeaderValue
|
||||
|
||||
return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization()
|
||||
}
|
||||
|
||||
// BearerAuthorizer implements the bearer authorization
|
||||
type BearerAuthorizer struct {
|
||||
tokenProvider adal.OAuthTokenProvider
|
||||
|
|
@ -55,7 +119,11 @@ func (ba *BearerAuthorizer) WithAuthorization() PrepareDecorator {
|
|||
if ok {
|
||||
err := refresher.EnsureFresh()
|
||||
if err != nil {
|
||||
return r, NewErrorWithError(err, "azure.BearerAuthorizer", "WithAuthorization", nil,
|
||||
var resp *http.Response
|
||||
if tokError, ok := err.(adal.TokenRefreshError); ok {
|
||||
resp = tokError.Response()
|
||||
}
|
||||
return r, NewErrorWithError(err, "azure.BearerAuthorizer", "WithAuthorization", resp,
|
||||
"Failed to refresh the Token for request to %s", r.URL)
|
||||
}
|
||||
}
|
||||
|
|
@ -165,3 +233,22 @@ func newBearerChallenge(resp *http.Response) (bc bearerChallenge, err error) {
|
|||
|
||||
return bc, err
|
||||
}
|
||||
|
||||
// EventGridKeyAuthorizer implements authorization for event grid using key authentication.
|
||||
type EventGridKeyAuthorizer struct {
|
||||
topicKey string
|
||||
}
|
||||
|
||||
// NewEventGridKeyAuthorizer creates a new EventGridKeyAuthorizer
|
||||
// with the specified topic key.
|
||||
func NewEventGridKeyAuthorizer(topicKey string) EventGridKeyAuthorizer {
|
||||
return EventGridKeyAuthorizer{topicKey: topicKey}
|
||||
}
|
||||
|
||||
// WithAuthorization returns a PrepareDecorator that adds the aeg-sas-key authentication header.
|
||||
func (egta EventGridKeyAuthorizer) WithAuthorization() PrepareDecorator {
|
||||
headers := map[string]interface{}{
|
||||
"aeg-sas-key": egta.topicKey,
|
||||
}
|
||||
return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization()
|
||||
}
|
||||
|
|
|
|||
17
vendor/github.com/Azure/go-autorest/autorest/autorest.go
generated
vendored
17
vendor/github.com/Azure/go-autorest/autorest/autorest.go
generated
vendored
|
|
@ -57,6 +57,20 @@ generated clients, see the Client described below.
|
|||
*/
|
||||
package autorest
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
|
@ -73,6 +87,9 @@ const (
|
|||
// ResponseHasStatusCode returns true if the status code in the HTTP Response is in the passed set
|
||||
// and false otherwise.
|
||||
func ResponseHasStatusCode(resp *http.Response, codes ...int) bool {
|
||||
if resp == nil {
|
||||
return false
|
||||
}
|
||||
return containsInt(codes, resp.StatusCode)
|
||||
}
|
||||
|
||||
|
|
|
|||
288
vendor/github.com/Azure/go-autorest/autorest/azure/async.go
generated
vendored
288
vendor/github.com/Azure/go-autorest/autorest/azure/async.go
generated
vendored
|
|
@ -1,7 +1,23 @@
|
|||
package azure
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
|
@ -23,6 +39,152 @@ const (
|
|||
operationSucceeded string = "Succeeded"
|
||||
)
|
||||
|
||||
var pollingCodes = [...]int{http.StatusNoContent, http.StatusAccepted, http.StatusCreated, http.StatusOK}
|
||||
|
||||
// Future provides a mechanism to access the status and results of an asynchronous request.
|
||||
// Since futures are stateful they should be passed by value to avoid race conditions.
|
||||
type Future struct {
|
||||
req *http.Request
|
||||
resp *http.Response
|
||||
ps pollingState
|
||||
}
|
||||
|
||||
// NewFuture returns a new Future object initialized with the specified request.
|
||||
func NewFuture(req *http.Request) Future {
|
||||
return Future{req: req}
|
||||
}
|
||||
|
||||
// Response returns the last HTTP response or nil if there isn't one.
|
||||
func (f Future) Response() *http.Response {
|
||||
return f.resp
|
||||
}
|
||||
|
||||
// Status returns the last status message of the operation.
|
||||
func (f Future) Status() string {
|
||||
if f.ps.State == "" {
|
||||
return "Unknown"
|
||||
}
|
||||
return f.ps.State
|
||||
}
|
||||
|
||||
// PollingMethod returns the method used to monitor the status of the asynchronous operation.
|
||||
func (f Future) PollingMethod() PollingMethodType {
|
||||
return f.ps.PollingMethod
|
||||
}
|
||||
|
||||
// Done queries the service to see if the operation has completed.
|
||||
func (f *Future) Done(sender autorest.Sender) (bool, error) {
|
||||
// exit early if this future has terminated
|
||||
if f.ps.hasTerminated() {
|
||||
return true, f.errorInfo()
|
||||
}
|
||||
|
||||
resp, err := sender.Do(f.req)
|
||||
f.resp = resp
|
||||
if err != nil || !autorest.ResponseHasStatusCode(resp, pollingCodes[:]...) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = updatePollingState(resp, &f.ps)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if f.ps.hasTerminated() {
|
||||
return true, f.errorInfo()
|
||||
}
|
||||
|
||||
f.req, err = newPollingRequest(f.ps)
|
||||
return false, err
|
||||
}
|
||||
|
||||
// GetPollingDelay returns a duration the application should wait before checking
|
||||
// the status of the asynchronous request and true; this value is returned from
|
||||
// the service via the Retry-After response header. If the header wasn't returned
|
||||
// then the function returns the zero-value time.Duration and false.
|
||||
func (f Future) GetPollingDelay() (time.Duration, bool) {
|
||||
if f.resp == nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
retry := f.resp.Header.Get(autorest.HeaderRetryAfter)
|
||||
if retry == "" {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
d, err := time.ParseDuration(retry + "s")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return d, true
|
||||
}
|
||||
|
||||
// WaitForCompletion will return when one of the following conditions is met: the long
|
||||
// running operation has completed, the provided context is cancelled, or the client's
|
||||
// polling duration has been exceeded. It will retry failed polling attempts based on
|
||||
// the retry value defined in the client up to the maximum retry attempts.
|
||||
func (f Future) WaitForCompletion(ctx context.Context, client autorest.Client) error {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.PollingDuration)
|
||||
defer cancel()
|
||||
|
||||
done, err := f.Done(client)
|
||||
for attempts := 0; !done; done, err = f.Done(client) {
|
||||
if attempts >= client.RetryAttempts {
|
||||
return autorest.NewErrorWithError(err, "azure", "WaitForCompletion", f.resp, "the number of retries has been exceeded")
|
||||
}
|
||||
// we want delayAttempt to be zero in the non-error case so
|
||||
// that DelayForBackoff doesn't perform exponential back-off
|
||||
var delayAttempt int
|
||||
var delay time.Duration
|
||||
if err == nil {
|
||||
// check for Retry-After delay, if not present use the client's polling delay
|
||||
var ok bool
|
||||
delay, ok = f.GetPollingDelay()
|
||||
if !ok {
|
||||
delay = client.PollingDelay
|
||||
}
|
||||
} else {
|
||||
// there was an error polling for status so perform exponential
|
||||
// back-off based on the number of attempts using the client's retry
|
||||
// duration. update attempts after delayAttempt to avoid off-by-one.
|
||||
delayAttempt = attempts
|
||||
delay = client.RetryDuration
|
||||
attempts++
|
||||
}
|
||||
// wait until the delay elapses or the context is cancelled
|
||||
delayElapsed := autorest.DelayForBackoff(delay, delayAttempt, ctx.Done())
|
||||
if !delayElapsed {
|
||||
return autorest.NewErrorWithError(ctx.Err(), "azure", "WaitForCompletion", f.resp, "context has been cancelled")
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// if the operation failed the polling state will contain
|
||||
// error information and implements the error interface
|
||||
func (f *Future) errorInfo() error {
|
||||
if !f.ps.hasSucceeded() {
|
||||
return f.ps
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (f Future) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(&f.ps)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
func (f *Future) UnmarshalJSON(data []byte) error {
|
||||
err := json.Unmarshal(data, &f.ps)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.req, err = newPollingRequest(f.ps)
|
||||
return err
|
||||
}
|
||||
|
||||
// DoPollForAsynchronous returns a SendDecorator that polls if the http.Response is for an Azure
|
||||
// long-running operation. It will delay between requests for the duration specified in the
|
||||
// RetryAfter header or, if the header is absent, the passed delay. Polling may be canceled by
|
||||
|
|
@ -34,8 +196,7 @@ func DoPollForAsynchronous(delay time.Duration) autorest.SendDecorator {
|
|||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
pollingCodes := []int{http.StatusAccepted, http.StatusCreated, http.StatusOK}
|
||||
if !autorest.ResponseHasStatusCode(resp, pollingCodes...) {
|
||||
if !autorest.ResponseHasStatusCode(resp, pollingCodes[:]...) {
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
|
|
@ -52,10 +213,11 @@ func DoPollForAsynchronous(delay time.Duration) autorest.SendDecorator {
|
|||
break
|
||||
}
|
||||
|
||||
r, err = newPollingRequest(resp, ps)
|
||||
r, err = newPollingRequest(ps)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
r.Cancel = resp.Request.Cancel
|
||||
|
||||
delay = autorest.GetRetryAfter(resp, delay)
|
||||
resp, err = autorest.SendWithSender(s, r,
|
||||
|
|
@ -72,20 +234,15 @@ func getAsyncOperation(resp *http.Response) string {
|
|||
}
|
||||
|
||||
func hasSucceeded(state string) bool {
|
||||
return state == operationSucceeded
|
||||
return strings.EqualFold(state, operationSucceeded)
|
||||
}
|
||||
|
||||
func hasTerminated(state string) bool {
|
||||
switch state {
|
||||
case operationCanceled, operationFailed, operationSucceeded:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return strings.EqualFold(state, operationCanceled) || strings.EqualFold(state, operationFailed) || strings.EqualFold(state, operationSucceeded)
|
||||
}
|
||||
|
||||
func hasFailed(state string) bool {
|
||||
return state == operationFailed
|
||||
return strings.EqualFold(state, operationFailed)
|
||||
}
|
||||
|
||||
type provisioningTracker interface {
|
||||
|
|
@ -146,36 +303,42 @@ func (ps provisioningStatus) hasProvisioningError() bool {
|
|||
return ps.ProvisioningError != ServiceError{}
|
||||
}
|
||||
|
||||
type pollingResponseFormat string
|
||||
// PollingMethodType defines a type used for enumerating polling mechanisms.
|
||||
type PollingMethodType string
|
||||
|
||||
const (
|
||||
usesOperationResponse pollingResponseFormat = "OperationResponse"
|
||||
usesProvisioningStatus pollingResponseFormat = "ProvisioningStatus"
|
||||
formatIsUnknown pollingResponseFormat = ""
|
||||
// PollingAsyncOperation indicates the polling method uses the Azure-AsyncOperation header.
|
||||
PollingAsyncOperation PollingMethodType = "AsyncOperation"
|
||||
|
||||
// PollingLocation indicates the polling method uses the Location header.
|
||||
PollingLocation PollingMethodType = "Location"
|
||||
|
||||
// PollingUnknown indicates an unknown polling method and is the default value.
|
||||
PollingUnknown PollingMethodType = ""
|
||||
)
|
||||
|
||||
type pollingState struct {
|
||||
responseFormat pollingResponseFormat
|
||||
uri string
|
||||
state string
|
||||
code string
|
||||
message string
|
||||
PollingMethod PollingMethodType `json:"pollingMethod"`
|
||||
URI string `json:"uri"`
|
||||
State string `json:"state"`
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func (ps pollingState) hasSucceeded() bool {
|
||||
return hasSucceeded(ps.state)
|
||||
return hasSucceeded(ps.State)
|
||||
}
|
||||
|
||||
func (ps pollingState) hasTerminated() bool {
|
||||
return hasTerminated(ps.state)
|
||||
return hasTerminated(ps.State)
|
||||
}
|
||||
|
||||
func (ps pollingState) hasFailed() bool {
|
||||
return hasFailed(ps.state)
|
||||
return hasFailed(ps.State)
|
||||
}
|
||||
|
||||
func (ps pollingState) Error() string {
|
||||
return fmt.Sprintf("Long running operation terminated with status '%s': Code=%q Message=%q", ps.state, ps.code, ps.message)
|
||||
return fmt.Sprintf("Long running operation terminated with status '%s': Code=%q Message=%q", ps.State, ps.Code, ps.Message)
|
||||
}
|
||||
|
||||
// updatePollingState maps the operation status -- retrieved from either a provisioningState
|
||||
|
|
@ -190,7 +353,7 @@ func updatePollingState(resp *http.Response, ps *pollingState) error {
|
|||
// -- The first response will always be a provisioningStatus response; only the polling requests,
|
||||
// depending on the header returned, may be something otherwise.
|
||||
var pt provisioningTracker
|
||||
if ps.responseFormat == usesOperationResponse {
|
||||
if ps.PollingMethod == PollingAsyncOperation {
|
||||
pt = &operationResource{}
|
||||
} else {
|
||||
pt = &provisioningStatus{}
|
||||
|
|
@ -198,30 +361,30 @@ func updatePollingState(resp *http.Response, ps *pollingState) error {
|
|||
|
||||
// If this is the first request (that is, the polling response shape is unknown), determine how
|
||||
// to poll and what to expect
|
||||
if ps.responseFormat == formatIsUnknown {
|
||||
if ps.PollingMethod == PollingUnknown {
|
||||
req := resp.Request
|
||||
if req == nil {
|
||||
return autorest.NewError("azure", "updatePollingState", "Azure Polling Error - Original HTTP request is missing")
|
||||
}
|
||||
|
||||
// Prefer the Azure-AsyncOperation header
|
||||
ps.uri = getAsyncOperation(resp)
|
||||
if ps.uri != "" {
|
||||
ps.responseFormat = usesOperationResponse
|
||||
ps.URI = getAsyncOperation(resp)
|
||||
if ps.URI != "" {
|
||||
ps.PollingMethod = PollingAsyncOperation
|
||||
} else {
|
||||
ps.responseFormat = usesProvisioningStatus
|
||||
ps.PollingMethod = PollingLocation
|
||||
}
|
||||
|
||||
// Else, use the Location header
|
||||
if ps.uri == "" {
|
||||
ps.uri = autorest.GetLocation(resp)
|
||||
if ps.URI == "" {
|
||||
ps.URI = autorest.GetLocation(resp)
|
||||
}
|
||||
|
||||
// Lastly, requests against an existing resource, use the last request URI
|
||||
if ps.uri == "" {
|
||||
if ps.URI == "" {
|
||||
m := strings.ToUpper(req.Method)
|
||||
if m == http.MethodPatch || m == http.MethodPut || m == http.MethodGet {
|
||||
ps.uri = req.URL.String()
|
||||
ps.URI = req.URL.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -242,23 +405,23 @@ func updatePollingState(resp *http.Response, ps *pollingState) error {
|
|||
// -- Unknown states are per-service inprogress states
|
||||
// -- Otherwise, infer state from HTTP status code
|
||||
if pt.hasTerminated() {
|
||||
ps.state = pt.state()
|
||||
ps.State = pt.state()
|
||||
} else if pt.state() != "" {
|
||||
ps.state = operationInProgress
|
||||
ps.State = operationInProgress
|
||||
} else {
|
||||
switch resp.StatusCode {
|
||||
case http.StatusAccepted:
|
||||
ps.state = operationInProgress
|
||||
ps.State = operationInProgress
|
||||
|
||||
case http.StatusNoContent, http.StatusCreated, http.StatusOK:
|
||||
ps.state = operationSucceeded
|
||||
ps.State = operationSucceeded
|
||||
|
||||
default:
|
||||
ps.state = operationFailed
|
||||
ps.State = operationFailed
|
||||
}
|
||||
}
|
||||
|
||||
if ps.state == operationInProgress && ps.uri == "" {
|
||||
if strings.EqualFold(ps.State, operationInProgress) && ps.URI == "" {
|
||||
return autorest.NewError("azure", "updatePollingState", "Azure Polling Error - Unable to obtain polling URI for %s %s", resp.Request.Method, resp.Request.URL)
|
||||
}
|
||||
|
||||
|
|
@ -267,36 +430,49 @@ func updatePollingState(resp *http.Response, ps *pollingState) error {
|
|||
// -- Response
|
||||
// -- Otherwise, Unknown
|
||||
if ps.hasFailed() {
|
||||
if ps.responseFormat == usesOperationResponse {
|
||||
if ps.PollingMethod == PollingAsyncOperation {
|
||||
or := pt.(*operationResource)
|
||||
ps.code = or.OperationError.Code
|
||||
ps.message = or.OperationError.Message
|
||||
ps.Code = or.OperationError.Code
|
||||
ps.Message = or.OperationError.Message
|
||||
} else {
|
||||
p := pt.(*provisioningStatus)
|
||||
if p.hasProvisioningError() {
|
||||
ps.code = p.ProvisioningError.Code
|
||||
ps.message = p.ProvisioningError.Message
|
||||
ps.Code = p.ProvisioningError.Code
|
||||
ps.Message = p.ProvisioningError.Message
|
||||
} else {
|
||||
ps.code = "Unknown"
|
||||
ps.message = "None"
|
||||
ps.Code = "Unknown"
|
||||
ps.Message = "None"
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func newPollingRequest(resp *http.Response, ps pollingState) (*http.Request, error) {
|
||||
req := resp.Request
|
||||
if req == nil {
|
||||
return nil, autorest.NewError("azure", "newPollingRequest", "Azure Polling Error - Original HTTP request is missing")
|
||||
}
|
||||
|
||||
reqPoll, err := autorest.Prepare(&http.Request{Cancel: req.Cancel},
|
||||
func newPollingRequest(ps pollingState) (*http.Request, error) {
|
||||
reqPoll, err := autorest.Prepare(&http.Request{},
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(ps.uri))
|
||||
autorest.WithBaseURL(ps.URI))
|
||||
if err != nil {
|
||||
return nil, autorest.NewErrorWithError(err, "azure", "newPollingRequest", nil, "Failure creating poll request to %s", ps.uri)
|
||||
return nil, autorest.NewErrorWithError(err, "azure", "newPollingRequest", nil, "Failure creating poll request to %s", ps.URI)
|
||||
}
|
||||
|
||||
return reqPoll, nil
|
||||
}
|
||||
|
||||
// AsyncOpIncompleteError is the type that's returned from a future that has not completed.
|
||||
type AsyncOpIncompleteError struct {
|
||||
// FutureType is the name of the type composed of a azure.Future.
|
||||
FutureType string
|
||||
}
|
||||
|
||||
// Error returns an error message including the originating type name of the error.
|
||||
func (e AsyncOpIncompleteError) Error() string {
|
||||
return fmt.Sprintf("%s: asynchronous operation has not completed", e.FutureType)
|
||||
}
|
||||
|
||||
// NewAsyncOpIncompleteError creates a new AsyncOpIncompleteError with the specified parameters.
|
||||
func NewAsyncOpIncompleteError(futureType string) AsyncOpIncompleteError {
|
||||
return AsyncOpIncompleteError{
|
||||
FutureType: futureType,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
22
vendor/github.com/Azure/go-autorest/autorest/azure/azure.go
generated
vendored
22
vendor/github.com/Azure/go-autorest/autorest/azure/azure.go
generated
vendored
|
|
@ -5,6 +5,20 @@ See the included examples for more detail.
|
|||
*/
|
||||
package azure
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
|
@ -165,7 +179,13 @@ func WithErrorUnlessStatusCode(codes ...int) autorest.RespondDecorator {
|
|||
if decodeErr != nil {
|
||||
return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b.String(), decodeErr)
|
||||
} else if e.ServiceError == nil {
|
||||
e.ServiceError = &ServiceError{Code: "Unknown", Message: "Unknown service error"}
|
||||
// Check if error is unwrapped ServiceError
|
||||
if err := json.Unmarshal(b.Bytes(), &e.ServiceError); err != nil || e.ServiceError.Message == "" {
|
||||
e.ServiceError = &ServiceError{
|
||||
Code: "Unknown",
|
||||
Message: "Unknown service error",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
e.RequestID = ExtractRequestID(resp)
|
||||
|
|
|
|||
52
vendor/github.com/Azure/go-autorest/autorest/azure/environments.go
generated
vendored
52
vendor/github.com/Azure/go-autorest/autorest/azure/environments.go
generated
vendored
|
|
@ -1,10 +1,31 @@
|
|||
package azure
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// EnvironmentFilepathName captures the name of the environment variable containing the path to the file
|
||||
// to be used while populating the Azure Environment.
|
||||
const EnvironmentFilepathName = "AZURE_ENVIRONMENT_FILEPATH"
|
||||
|
||||
var environments = map[string]Environment{
|
||||
"AZURECHINACLOUD": ChinaCloud,
|
||||
"AZUREGERMANCLOUD": GermanCloud,
|
||||
|
|
@ -62,10 +83,10 @@ var (
|
|||
PublishSettingsURL: "https://manage.windowsazure.us/publishsettings/index",
|
||||
ServiceManagementEndpoint: "https://management.core.usgovcloudapi.net/",
|
||||
ResourceManagerEndpoint: "https://management.usgovcloudapi.net/",
|
||||
ActiveDirectoryEndpoint: "https://login.microsoftonline.com/",
|
||||
ActiveDirectoryEndpoint: "https://login.microsoftonline.us/",
|
||||
GalleryEndpoint: "https://gallery.usgovcloudapi.net/",
|
||||
KeyVaultEndpoint: "https://vault.usgovcloudapi.net/",
|
||||
GraphEndpoint: "https://graph.usgovcloudapi.net/",
|
||||
GraphEndpoint: "https://graph.windows.net/",
|
||||
StorageEndpointSuffix: "core.usgovcloudapi.net",
|
||||
SQLDatabaseDNSSuffix: "database.usgovcloudapi.net",
|
||||
TrafficManagerDNSSuffix: "usgovtrafficmanager.net",
|
||||
|
|
@ -119,12 +140,37 @@ var (
|
|||
}
|
||||
)
|
||||
|
||||
// EnvironmentFromName returns an Environment based on the common name specified
|
||||
// EnvironmentFromName returns an Environment based on the common name specified.
|
||||
func EnvironmentFromName(name string) (Environment, error) {
|
||||
// IMPORTANT
|
||||
// As per @radhikagupta5:
|
||||
// This is technical debt, fundamentally here because Kubernetes is not currently accepting
|
||||
// contributions to the providers. Once that is an option, the provider should be updated to
|
||||
// directly call `EnvironmentFromFile`. Until then, we rely on dispatching Azure Stack environment creation
|
||||
// from this method based on the name that is provided to us.
|
||||
if strings.EqualFold(name, "AZURESTACKCLOUD") {
|
||||
return EnvironmentFromFile(os.Getenv(EnvironmentFilepathName))
|
||||
}
|
||||
|
||||
name = strings.ToUpper(name)
|
||||
env, ok := environments[name]
|
||||
if !ok {
|
||||
return env, fmt.Errorf("autorest/azure: There is no cloud environment matching the name %q", name)
|
||||
}
|
||||
|
||||
return env, nil
|
||||
}
|
||||
|
||||
// EnvironmentFromFile loads an Environment from a configuration file available on disk.
|
||||
// This function is particularly useful in the Hybrid Cloud model, where one must define their own
|
||||
// endpoints.
|
||||
func EnvironmentFromFile(location string) (unmarshaled Environment, err error) {
|
||||
fileContents, err := ioutil.ReadFile(location)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = json.Unmarshal(fileContents, &unmarshaled)
|
||||
|
||||
return
|
||||
}
|
||||
|
|
|
|||
203
vendor/github.com/Azure/go-autorest/autorest/azure/rp.go
generated
vendored
Normal file
203
vendor/github.com/Azure/go-autorest/autorest/azure/rp.go
generated
vendored
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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 azure
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
)
|
||||
|
||||
// DoRetryWithRegistration tries to register the resource provider in case it is unregistered.
|
||||
// It also handles request retries
|
||||
func DoRetryWithRegistration(client autorest.Client) autorest.SendDecorator {
|
||||
return func(s autorest.Sender) autorest.Sender {
|
||||
return autorest.SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
||||
rr := autorest.NewRetriableRequest(r)
|
||||
for currentAttempt := 0; currentAttempt < client.RetryAttempts; currentAttempt++ {
|
||||
err = rr.Prepare()
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
resp, err = autorest.SendWithSender(s, rr.Request(),
|
||||
autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...),
|
||||
)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusConflict || client.SkipResourceProviderRegistration {
|
||||
return resp, err
|
||||
}
|
||||
var re RequestError
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
autorest.ByUnmarshallingJSON(&re),
|
||||
)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
err = re
|
||||
|
||||
if re.ServiceError != nil && re.ServiceError.Code == "MissingSubscriptionRegistration" {
|
||||
regErr := register(client, r, re)
|
||||
if regErr != nil {
|
||||
return resp, fmt.Errorf("failed auto registering Resource Provider: %s. Original error: %s", regErr, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return resp, fmt.Errorf("failed request: %s", err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func getProvider(re RequestError) (string, error) {
|
||||
if re.ServiceError != nil {
|
||||
if re.ServiceError.Details != nil && len(*re.ServiceError.Details) > 0 {
|
||||
detail := (*re.ServiceError.Details)[0].(map[string]interface{})
|
||||
return detail["target"].(string), nil
|
||||
}
|
||||
}
|
||||
return "", errors.New("provider was not found in the response")
|
||||
}
|
||||
|
||||
func register(client autorest.Client, originalReq *http.Request, re RequestError) error {
|
||||
subID := getSubscription(originalReq.URL.Path)
|
||||
if subID == "" {
|
||||
return errors.New("missing parameter subscriptionID to register resource provider")
|
||||
}
|
||||
providerName, err := getProvider(re)
|
||||
if err != nil {
|
||||
return fmt.Errorf("missing parameter provider to register resource provider: %s", err)
|
||||
}
|
||||
newURL := url.URL{
|
||||
Scheme: originalReq.URL.Scheme,
|
||||
Host: originalReq.URL.Host,
|
||||
}
|
||||
|
||||
// taken from the resources SDK
|
||||
// with almost identical code, this sections are easier to mantain
|
||||
// It is also not a good idea to import the SDK here
|
||||
// https://github.com/Azure/azure-sdk-for-go/blob/9f366792afa3e0ddaecdc860e793ba9d75e76c27/arm/resources/resources/providers.go#L252
|
||||
pathParameters := map[string]interface{}{
|
||||
"resourceProviderNamespace": autorest.Encode("path", providerName),
|
||||
"subscriptionId": autorest.Encode("path", subID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsPost(),
|
||||
autorest.WithBaseURL(newURL.String()),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/register", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters),
|
||||
)
|
||||
|
||||
req, err := preparer.Prepare(&http.Request{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Cancel = originalReq.Cancel
|
||||
|
||||
resp, err := autorest.SendWithSender(client, req,
|
||||
autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type Provider struct {
|
||||
RegistrationState *string `json:"registrationState,omitempty"`
|
||||
}
|
||||
var provider Provider
|
||||
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&provider),
|
||||
autorest.ByClosing(),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// poll for registered provisioning state
|
||||
now := time.Now()
|
||||
for err == nil && time.Since(now) < client.PollingDuration {
|
||||
// taken from the resources SDK
|
||||
// https://github.com/Azure/azure-sdk-for-go/blob/9f366792afa3e0ddaecdc860e793ba9d75e76c27/arm/resources/resources/providers.go#L45
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(newURL.String()),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters),
|
||||
)
|
||||
req, err = preparer.Prepare(&http.Request{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Cancel = originalReq.Cancel
|
||||
|
||||
resp, err := autorest.SendWithSender(client, req,
|
||||
autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&provider),
|
||||
autorest.ByClosing(),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if provider.RegistrationState != nil &&
|
||||
*provider.RegistrationState == "Registered" {
|
||||
break
|
||||
}
|
||||
|
||||
delayed := autorest.DelayWithRetryAfter(resp, originalReq.Cancel)
|
||||
if !delayed {
|
||||
autorest.DelayForBackoff(client.PollingDelay, 0, originalReq.Cancel)
|
||||
}
|
||||
}
|
||||
if !(time.Since(now) < client.PollingDuration) {
|
||||
return errors.New("polling for resource provider registration has exceeded the polling duration")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func getSubscription(path string) string {
|
||||
parts := strings.Split(path, "/")
|
||||
for i, v := range parts {
|
||||
if v == "subscriptions" && (i+1) < len(parts) {
|
||||
return parts[i+1]
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
41
vendor/github.com/Azure/go-autorest/autorest/client.go
generated
vendored
41
vendor/github.com/Azure/go-autorest/autorest/client.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package autorest
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
|
@ -21,6 +35,9 @@ const (
|
|||
|
||||
// DefaultRetryAttempts is number of attempts for retry status codes (5xx).
|
||||
DefaultRetryAttempts = 3
|
||||
|
||||
// DefaultRetryDuration is the duration to wait between retries.
|
||||
DefaultRetryDuration = 30 * time.Second
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -33,7 +50,8 @@ var (
|
|||
Version(),
|
||||
)
|
||||
|
||||
statusCodesForRetry = []int{
|
||||
// StatusCodesForRetry are a defined group of status code for which the client will retry
|
||||
StatusCodesForRetry = []int{
|
||||
http.StatusRequestTimeout, // 408
|
||||
http.StatusTooManyRequests, // 429
|
||||
http.StatusInternalServerError, // 500
|
||||
|
|
@ -148,6 +166,9 @@ type Client struct {
|
|||
UserAgent string
|
||||
|
||||
Jar http.CookieJar
|
||||
|
||||
// Set to true to skip attempted registration of resource providers (false by default).
|
||||
SkipResourceProviderRegistration bool
|
||||
}
|
||||
|
||||
// NewClientWithUserAgent returns an instance of a Client with the UserAgent set to the passed
|
||||
|
|
@ -157,9 +178,10 @@ func NewClientWithUserAgent(ua string) Client {
|
|||
PollingDelay: DefaultPollingDelay,
|
||||
PollingDuration: DefaultPollingDuration,
|
||||
RetryAttempts: DefaultRetryAttempts,
|
||||
RetryDuration: 30 * time.Second,
|
||||
RetryDuration: DefaultRetryDuration,
|
||||
UserAgent: defaultUserAgent,
|
||||
}
|
||||
c.Sender = c.sender()
|
||||
c.AddToUserAgent(ua)
|
||||
return c
|
||||
}
|
||||
|
|
@ -185,12 +207,17 @@ func (c Client) Do(r *http.Request) (*http.Response, error) {
|
|||
c.WithInspection(),
|
||||
c.WithAuthorization())
|
||||
if err != nil {
|
||||
return nil, NewErrorWithError(err, "autorest/Client", "Do", nil, "Preparing request failed")
|
||||
var resp *http.Response
|
||||
if detErr, ok := err.(DetailedError); ok {
|
||||
// if the authorization failed (e.g. invalid credentials) there will
|
||||
// be a response associated with the error, be sure to return it.
|
||||
resp = detErr.Response
|
||||
}
|
||||
return resp, NewErrorWithError(err, "autorest/Client", "Do", nil, "Preparing request failed")
|
||||
}
|
||||
resp, err := SendWithSender(c.sender(), r,
|
||||
DoRetryForStatusCodes(c.RetryAttempts, c.RetryDuration, statusCodesForRetry...))
|
||||
Respond(resp,
|
||||
c.ByInspecting())
|
||||
|
||||
resp, err := SendWithSender(c.sender(), r)
|
||||
Respond(resp, c.ByInspecting())
|
||||
return resp, err
|
||||
}
|
||||
|
||||
|
|
|
|||
14
vendor/github.com/Azure/go-autorest/autorest/date/date.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/date/date.go
generated
vendored
|
|
@ -5,6 +5,20 @@ time.Time types. And both convert to time.Time through a ToTime method.
|
|||
*/
|
||||
package date
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
|
|
|||
14
vendor/github.com/Azure/go-autorest/autorest/date/time.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/date/time.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package date
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"time"
|
||||
|
|
|
|||
14
vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package date
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
|
|
|||
14
vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package date
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
|
|
|
|||
14
vendor/github.com/Azure/go-autorest/autorest/date/utility.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/date/utility.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package date
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
|
|
|||
14
vendor/github.com/Azure/go-autorest/autorest/error.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/error.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package autorest
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
|
|
|||
60
vendor/github.com/Azure/go-autorest/autorest/preparer.go
generated
vendored
60
vendor/github.com/Azure/go-autorest/autorest/preparer.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package autorest
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
|
@ -13,8 +27,9 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
mimeTypeJSON = "application/json"
|
||||
mimeTypeFormPost = "application/x-www-form-urlencoded"
|
||||
mimeTypeJSON = "application/json"
|
||||
mimeTypeOctetStream = "application/octet-stream"
|
||||
mimeTypeFormPost = "application/x-www-form-urlencoded"
|
||||
|
||||
headerAuthorization = "Authorization"
|
||||
headerContentType = "Content-Type"
|
||||
|
|
@ -98,6 +113,28 @@ func WithHeader(header string, value string) PrepareDecorator {
|
|||
}
|
||||
}
|
||||
|
||||
// WithHeaders returns a PrepareDecorator that sets the specified HTTP headers of the http.Request to
|
||||
// the passed value. It canonicalizes the passed headers name (via http.CanonicalHeaderKey) before
|
||||
// adding them.
|
||||
func WithHeaders(headers map[string]interface{}) PrepareDecorator {
|
||||
h := ensureValueStrings(headers)
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
if r.Header == nil {
|
||||
r.Header = make(http.Header)
|
||||
}
|
||||
|
||||
for name, value := range h {
|
||||
r.Header.Set(http.CanonicalHeaderKey(name), value)
|
||||
}
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithBearerAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose
|
||||
// value is "Bearer " followed by the supplied token.
|
||||
func WithBearerAuthorization(token string) PrepareDecorator {
|
||||
|
|
@ -128,6 +165,11 @@ func AsJSON() PrepareDecorator {
|
|||
return AsContentType(mimeTypeJSON)
|
||||
}
|
||||
|
||||
// AsOctetStream returns a PrepareDecorator that adds the "application/octet-stream" Content-Type header.
|
||||
func AsOctetStream() PrepareDecorator {
|
||||
return AsContentType(mimeTypeOctetStream)
|
||||
}
|
||||
|
||||
// WithMethod returns a PrepareDecorator that sets the HTTP method of the passed request. The
|
||||
// decorator does not validate that the passed method string is a known HTTP method.
|
||||
func WithMethod(method string) PrepareDecorator {
|
||||
|
|
@ -201,6 +243,11 @@ func WithFormData(v url.Values) PrepareDecorator {
|
|||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
s := v.Encode()
|
||||
|
||||
if r.Header == nil {
|
||||
r.Header = make(http.Header)
|
||||
}
|
||||
r.Header.Set(http.CanonicalHeaderKey(headerContentType), mimeTypeFormPost)
|
||||
r.ContentLength = int64(len(s))
|
||||
r.Body = ioutil.NopCloser(strings.NewReader(s))
|
||||
}
|
||||
|
|
@ -416,11 +463,16 @@ func WithQueryParameters(queryParameters map[string]interface{}) PrepareDecorato
|
|||
if r.URL == nil {
|
||||
return r, NewError("autorest", "WithQueryParameters", "Invoked with a nil URL")
|
||||
}
|
||||
|
||||
v := r.URL.Query()
|
||||
for key, value := range parameters {
|
||||
v.Add(key, value)
|
||||
d, err := url.QueryUnescape(value)
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
v.Add(key, d)
|
||||
}
|
||||
r.URL.RawQuery = createQuery(v)
|
||||
r.URL.RawQuery = v.Encode()
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
|
|
|
|||
14
vendor/github.com/Azure/go-autorest/autorest/responder.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/responder.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package autorest
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
|
|
|||
14
vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go
generated
vendored
14
vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package autorest
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
|
|
|
|||
36
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go
generated
vendored
36
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go
generated
vendored
|
|
@ -1,17 +1,31 @@
|
|||
// +build !go1.8
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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 autorest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// RetriableRequest provides facilities for retrying an HTTP request.
|
||||
type RetriableRequest struct {
|
||||
req *http.Request
|
||||
br *bytes.Reader
|
||||
reset bool
|
||||
req *http.Request
|
||||
br *bytes.Reader
|
||||
}
|
||||
|
||||
// Prepare signals that the request is about to be sent.
|
||||
|
|
@ -19,21 +33,17 @@ func (rr *RetriableRequest) Prepare() (err error) {
|
|||
// preserve the request body; this is to support retry logic as
|
||||
// the underlying transport will always close the reqeust body
|
||||
if rr.req.Body != nil {
|
||||
if rr.reset {
|
||||
if rr.br != nil {
|
||||
_, err = rr.br.Seek(0, 0 /*io.SeekStart*/)
|
||||
}
|
||||
rr.reset = false
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rr.br != nil {
|
||||
_, err = rr.br.Seek(0, 0 /*io.SeekStart*/)
|
||||
rr.req.Body = ioutil.NopCloser(rr.br)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rr.br == nil {
|
||||
// fall back to making a copy (only do this once)
|
||||
err = rr.prepareFromByteReader()
|
||||
}
|
||||
// indicates that the request body needs to be reset
|
||||
rr.reset = true
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
42
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go
generated
vendored
42
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go
generated
vendored
|
|
@ -1,19 +1,33 @@
|
|||
// +build go1.8
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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 autorest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// RetriableRequest provides facilities for retrying an HTTP request.
|
||||
type RetriableRequest struct {
|
||||
req *http.Request
|
||||
rc io.ReadCloser
|
||||
br *bytes.Reader
|
||||
reset bool
|
||||
req *http.Request
|
||||
rc io.ReadCloser
|
||||
br *bytes.Reader
|
||||
}
|
||||
|
||||
// Prepare signals that the request is about to be sent.
|
||||
|
|
@ -21,16 +35,14 @@ func (rr *RetriableRequest) Prepare() (err error) {
|
|||
// preserve the request body; this is to support retry logic as
|
||||
// the underlying transport will always close the reqeust body
|
||||
if rr.req.Body != nil {
|
||||
if rr.reset {
|
||||
if rr.rc != nil {
|
||||
rr.req.Body = rr.rc
|
||||
} else if rr.br != nil {
|
||||
_, err = rr.br.Seek(0, io.SeekStart)
|
||||
}
|
||||
rr.reset = false
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rr.rc != nil {
|
||||
rr.req.Body = rr.rc
|
||||
} else if rr.br != nil {
|
||||
_, err = rr.br.Seek(0, io.SeekStart)
|
||||
rr.req.Body = ioutil.NopCloser(rr.br)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rr.req.GetBody != nil {
|
||||
// this will allow us to preserve the body without having to
|
||||
|
|
@ -43,8 +55,6 @@ func (rr *RetriableRequest) Prepare() (err error) {
|
|||
// fall back to making a copy (only do this once)
|
||||
err = rr.prepareFromByteReader()
|
||||
}
|
||||
// indicates that the request body needs to be reset
|
||||
rr.reset = true
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
28
vendor/github.com/Azure/go-autorest/autorest/sender.go
generated
vendored
28
vendor/github.com/Azure/go-autorest/autorest/sender.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package autorest
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
|
@ -201,19 +215,26 @@ func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) Se
|
|||
rr := NewRetriableRequest(r)
|
||||
// Increment to add the first call (attempts denotes number of retries)
|
||||
attempts++
|
||||
for attempt := 0; attempt < attempts; attempt++ {
|
||||
for attempt := 0; attempt < attempts; {
|
||||
err = rr.Prepare()
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
resp, err = s.Do(rr.Request())
|
||||
if err != nil || !ResponseHasStatusCode(resp, codes...) {
|
||||
// we want to retry if err is not nil (e.g. transient network failure). note that for failed authentication
|
||||
// resp and err will both have a value, so in this case we don't want to retry as it will never succeed.
|
||||
if err == nil && !ResponseHasStatusCode(resp, codes...) || IsTokenRefreshError(err) {
|
||||
return resp, err
|
||||
}
|
||||
delayed := DelayWithRetryAfter(resp, r.Cancel)
|
||||
if !delayed {
|
||||
DelayForBackoff(backoff, attempt, r.Cancel)
|
||||
}
|
||||
// don't count a 429 against the number of attempts
|
||||
// so that we continue to retry until it succeeds
|
||||
if resp == nil || resp.StatusCode != http.StatusTooManyRequests {
|
||||
attempt++
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
})
|
||||
|
|
@ -223,6 +244,9 @@ func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) Se
|
|||
// DelayWithRetryAfter invokes time.After for the duration specified in the "Retry-After" header in
|
||||
// responses with status code 429
|
||||
func DelayWithRetryAfter(resp *http.Response, cancel <-chan struct{}) bool {
|
||||
if resp == nil {
|
||||
return false
|
||||
}
|
||||
retryAfter, _ := strconv.Atoi(resp.Header.Get("Retry-After"))
|
||||
if resp.StatusCode == http.StatusTooManyRequests && retryAfter > 0 {
|
||||
select {
|
||||
|
|
|
|||
98
vendor/github.com/Azure/go-autorest/autorest/utility.go
generated
vendored
98
vendor/github.com/Azure/go-autorest/autorest/utility.go
generated
vendored
|
|
@ -1,15 +1,31 @@
|
|||
package autorest
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest/adal"
|
||||
)
|
||||
|
||||
// EncodedAs is a series of constants specifying various data encodings
|
||||
|
|
@ -123,13 +139,38 @@ func MapToValues(m map[string]interface{}) url.Values {
|
|||
return v
|
||||
}
|
||||
|
||||
// String method converts interface v to string. If interface is a list, it
|
||||
// joins list elements using separator.
|
||||
func String(v interface{}, sep ...string) string {
|
||||
if len(sep) > 0 {
|
||||
return ensureValueString(strings.Join(v.([]string), sep[0]))
|
||||
// AsStringSlice method converts interface{} to []string. This expects a
|
||||
//that the parameter passed to be a slice or array of a type that has the underlying
|
||||
//type a string.
|
||||
func AsStringSlice(s interface{}) ([]string, error) {
|
||||
v := reflect.ValueOf(s)
|
||||
if v.Kind() != reflect.Slice && v.Kind() != reflect.Array {
|
||||
return nil, NewError("autorest", "AsStringSlice", "the value's type is not an array.")
|
||||
}
|
||||
return ensureValueString(v)
|
||||
stringSlice := make([]string, 0, v.Len())
|
||||
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
stringSlice = append(stringSlice, v.Index(i).String())
|
||||
}
|
||||
return stringSlice, nil
|
||||
}
|
||||
|
||||
// String method converts interface v to string. If interface is a list, it
|
||||
// joins list elements using the seperator. Note that only sep[0] will be used for
|
||||
// joining if any separator is specified.
|
||||
func String(v interface{}, sep ...string) string {
|
||||
if len(sep) == 0 {
|
||||
return ensureValueString(v)
|
||||
}
|
||||
stringSlice, ok := v.([]string)
|
||||
if ok == false {
|
||||
var err error
|
||||
stringSlice, err = AsStringSlice(v)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("autorest: Couldn't convert value to a string %s.", err))
|
||||
}
|
||||
}
|
||||
return ensureValueString(strings.Join(stringSlice, sep[0]))
|
||||
}
|
||||
|
||||
// Encode method encodes url path and query parameters.
|
||||
|
|
@ -153,26 +194,25 @@ func queryEscape(s string) string {
|
|||
return url.QueryEscape(s)
|
||||
}
|
||||
|
||||
// This method is same as Encode() method of "net/url" go package,
|
||||
// except it does not encode the query parameters because they
|
||||
// already come encoded. It formats values map in query format (bar=foo&a=b).
|
||||
func createQuery(v url.Values) string {
|
||||
var buf bytes.Buffer
|
||||
keys := make([]string, 0, len(v))
|
||||
for k := range v {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
vs := v[k]
|
||||
prefix := url.QueryEscape(k) + "="
|
||||
for _, v := range vs {
|
||||
if buf.Len() > 0 {
|
||||
buf.WriteByte('&')
|
||||
}
|
||||
buf.WriteString(prefix)
|
||||
buf.WriteString(v)
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
// ChangeToGet turns the specified http.Request into a GET (it assumes it wasn't).
|
||||
// This is mainly useful for long-running operations that use the Azure-AsyncOperation
|
||||
// header, so we change the initial PUT into a GET to retrieve the final result.
|
||||
func ChangeToGet(req *http.Request) *http.Request {
|
||||
req.Method = "GET"
|
||||
req.Body = nil
|
||||
req.ContentLength = 0
|
||||
req.Header.Del("Content-Length")
|
||||
return req
|
||||
}
|
||||
|
||||
// IsTokenRefreshError returns true if the specified error implements the TokenRefreshError
|
||||
// interface. If err is a DetailedError it will walk the chain of Original errors.
|
||||
func IsTokenRefreshError(err error) bool {
|
||||
if _, ok := err.(adal.TokenRefreshError); ok {
|
||||
return true
|
||||
}
|
||||
if de, ok := err.(DetailedError); ok {
|
||||
return IsTokenRefreshError(de.Original)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
20
vendor/github.com/Azure/go-autorest/autorest/version.go
generated
vendored
20
vendor/github.com/Azure/go-autorest/autorest/version.go
generated
vendored
|
|
@ -1,5 +1,19 @@
|
|||
package autorest
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
|
@ -8,9 +22,9 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
major = 8
|
||||
minor = 0
|
||||
patch = 0
|
||||
major = 9
|
||||
minor = 8
|
||||
patch = 1
|
||||
tag = ""
|
||||
)
|
||||
|
||||
|
|
|
|||
58
vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
generated
vendored
58
vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
generated
vendored
|
|
@ -2,6 +2,7 @@ package client
|
|||
|
||||
import (
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
|
@ -38,14 +39,18 @@ func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration {
|
|||
minTime := 30
|
||||
throttle := d.shouldThrottle(r)
|
||||
if throttle {
|
||||
if delay, ok := getRetryDelay(r); ok {
|
||||
return delay
|
||||
}
|
||||
|
||||
minTime = 500
|
||||
}
|
||||
|
||||
retryCount := r.RetryCount
|
||||
if retryCount > 13 {
|
||||
retryCount = 13
|
||||
} else if throttle && retryCount > 8 {
|
||||
if throttle && retryCount > 8 {
|
||||
retryCount = 8
|
||||
} else if retryCount > 13 {
|
||||
retryCount = 13
|
||||
}
|
||||
|
||||
delay := (1 << uint(retryCount)) * (seededRand.Intn(minTime) + minTime)
|
||||
|
|
@ -68,12 +73,49 @@ func (d DefaultRetryer) ShouldRetry(r *request.Request) bool {
|
|||
|
||||
// ShouldThrottle returns true if the request should be throttled.
|
||||
func (d DefaultRetryer) shouldThrottle(r *request.Request) bool {
|
||||
if r.HTTPResponse.StatusCode == 502 ||
|
||||
r.HTTPResponse.StatusCode == 503 ||
|
||||
r.HTTPResponse.StatusCode == 504 {
|
||||
return true
|
||||
switch r.HTTPResponse.StatusCode {
|
||||
case 429:
|
||||
case 502:
|
||||
case 503:
|
||||
case 504:
|
||||
default:
|
||||
return r.IsErrorThrottle()
|
||||
}
|
||||
return r.IsErrorThrottle()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// This will look in the Retry-After header, RFC 7231, for how long
|
||||
// it will wait before attempting another request
|
||||
func getRetryDelay(r *request.Request) (time.Duration, bool) {
|
||||
if !canUseRetryAfterHeader(r) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
delayStr := r.HTTPResponse.Header.Get("Retry-After")
|
||||
if len(delayStr) == 0 {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
delay, err := strconv.Atoi(delayStr)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return time.Duration(delay) * time.Second, true
|
||||
}
|
||||
|
||||
// Will look at the status code to see if the retry header pertains to
|
||||
// the status code.
|
||||
func canUseRetryAfterHeader(r *request.Request) bool {
|
||||
switch r.HTTPResponse.StatusCode {
|
||||
case 429:
|
||||
case 503:
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// lockedSource is a thread-safe implementation of rand.Source
|
||||
|
|
|
|||
2
vendor/github.com/aws/aws-sdk-go/aws/config.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go/aws/config.go
generated
vendored
|
|
@ -168,7 +168,7 @@ type Config struct {
|
|||
//
|
||||
EC2MetadataDisableTimeoutOverride *bool
|
||||
|
||||
// Instructs the endpiont to be generated for a service client to
|
||||
// Instructs the endpoint to be generated for a service client to
|
||||
// be the dual stack endpoint. The dual stack endpoint will support
|
||||
// both IPv4 and IPv6 addressing.
|
||||
//
|
||||
|
|
|
|||
34
vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go
generated
vendored
34
vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go
generated
vendored
|
|
@ -9,6 +9,7 @@ package defaults
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
|
|
@ -118,14 +119,43 @@ func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.P
|
|||
return ec2RoleProvider(cfg, handlers)
|
||||
}
|
||||
|
||||
var lookupHostFn = net.LookupHost
|
||||
|
||||
func isLoopbackHost(host string) (bool, error) {
|
||||
ip := net.ParseIP(host)
|
||||
if ip != nil {
|
||||
return ip.IsLoopback(), nil
|
||||
}
|
||||
|
||||
// Host is not an ip, perform lookup
|
||||
addrs, err := lookupHostFn(host)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
if !net.ParseIP(addr).IsLoopback() {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func localHTTPCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider {
|
||||
var errMsg string
|
||||
|
||||
parsed, err := url.Parse(u)
|
||||
if err != nil {
|
||||
errMsg = fmt.Sprintf("invalid URL, %v", err)
|
||||
} else if host := aws.URLHostname(parsed); !(host == "localhost" || host == "127.0.0.1") {
|
||||
errMsg = fmt.Sprintf("invalid host address, %q, only localhost and 127.0.0.1 are valid.", host)
|
||||
} else {
|
||||
host := aws.URLHostname(parsed)
|
||||
if len(host) == 0 {
|
||||
errMsg = "unable to parse host from local HTTP cred provider URL"
|
||||
} else if isLoopback, loopbackErr := isLoopbackHost(host); loopbackErr != nil {
|
||||
errMsg = fmt.Sprintf("failed to resolve host %q, %v", host, loopbackErr)
|
||||
} else if !isLoopback {
|
||||
errMsg = fmt.Sprintf("invalid endpoint host, %q, only loopback hosts are allowed.", host)
|
||||
}
|
||||
}
|
||||
|
||||
if len(errMsg) > 0 {
|
||||
|
|
|
|||
24
vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go
generated
vendored
24
vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go
generated
vendored
|
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
)
|
||||
|
|
@ -84,11 +85,34 @@ func decodeV3Endpoints(modelDef modelDefinition, opts DecodeModelOptions) (Resol
|
|||
custAddEC2Metadata(p)
|
||||
custAddS3DualStack(p)
|
||||
custRmIotDataService(p)
|
||||
|
||||
custFixCloudHSMv2SigningName(p)
|
||||
}
|
||||
|
||||
return ps, nil
|
||||
}
|
||||
|
||||
func custFixCloudHSMv2SigningName(p *partition) {
|
||||
// Workaround for aws/aws-sdk-go#1745 until the endpoint model can be
|
||||
// fixed upstream. TODO remove this once the endpoints model is updated.
|
||||
|
||||
s, ok := p.Services["cloudhsmv2"]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if len(s.Defaults.CredentialScope.Service) != 0 {
|
||||
fmt.Fprintf(os.Stderr, "cloudhsmv2 signing name already set, ignoring override.\n")
|
||||
// If the value is already set don't override
|
||||
return
|
||||
}
|
||||
|
||||
s.Defaults.CredentialScope.Service = "cloudhsm"
|
||||
fmt.Fprintf(os.Stderr, "cloudhsmv2 signing name not set, overriding.\n")
|
||||
|
||||
p.Services["cloudhsmv2"] = s
|
||||
}
|
||||
|
||||
func custAddS3DualStack(p *partition) {
|
||||
if p.ID != "aws" {
|
||||
return
|
||||
|
|
|
|||
317
vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
generated
vendored
317
vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
generated
vendored
|
|
@ -24,6 +24,7 @@ const (
|
|||
EuCentral1RegionID = "eu-central-1" // EU (Frankfurt).
|
||||
EuWest1RegionID = "eu-west-1" // EU (Ireland).
|
||||
EuWest2RegionID = "eu-west-2" // EU (London).
|
||||
EuWest3RegionID = "eu-west-3" // EU (Paris).
|
||||
SaEast1RegionID = "sa-east-1" // South America (Sao Paulo).
|
||||
UsEast1RegionID = "us-east-1" // US East (N. Virginia).
|
||||
UsEast2RegionID = "us-east-2" // US East (Ohio).
|
||||
|
|
@ -33,7 +34,8 @@ const (
|
|||
|
||||
// AWS China partition's regions.
|
||||
const (
|
||||
CnNorth1RegionID = "cn-north-1" // China (Beijing).
|
||||
CnNorth1RegionID = "cn-north-1" // China (Beijing).
|
||||
CnNorthwest1RegionID = "cn-northwest-1" // China (Ningxia).
|
||||
)
|
||||
|
||||
// AWS GovCloud (US) partition's regions.
|
||||
|
|
@ -44,11 +46,13 @@ const (
|
|||
// Service identifiers
|
||||
const (
|
||||
AcmServiceID = "acm" // Acm.
|
||||
ApiPricingServiceID = "api.pricing" // ApiPricing.
|
||||
ApigatewayServiceID = "apigateway" // Apigateway.
|
||||
ApplicationAutoscalingServiceID = "application-autoscaling" // ApplicationAutoscaling.
|
||||
Appstream2ServiceID = "appstream2" // Appstream2.
|
||||
AthenaServiceID = "athena" // Athena.
|
||||
AutoscalingServiceID = "autoscaling" // Autoscaling.
|
||||
AutoscalingPlansServiceID = "autoscaling-plans" // AutoscalingPlans.
|
||||
BatchServiceID = "batch" // Batch.
|
||||
BudgetsServiceID = "budgets" // Budgets.
|
||||
ClouddirectoryServiceID = "clouddirectory" // Clouddirectory.
|
||||
|
|
@ -69,6 +73,7 @@ const (
|
|||
ConfigServiceID = "config" // Config.
|
||||
CurServiceID = "cur" // Cur.
|
||||
DatapipelineServiceID = "datapipeline" // Datapipeline.
|
||||
DaxServiceID = "dax" // Dax.
|
||||
DevicefarmServiceID = "devicefarm" // Devicefarm.
|
||||
DirectconnectServiceID = "directconnect" // Directconnect.
|
||||
DiscoveryServiceID = "discovery" // Discovery.
|
||||
|
|
@ -220,6 +225,9 @@ var awsPartition = partition{
|
|||
"eu-west-2": region{
|
||||
Description: "EU (London)",
|
||||
},
|
||||
"eu-west-3": region{
|
||||
Description: "EU (Paris)",
|
||||
},
|
||||
"sa-east-1": region{
|
||||
Description: "South America (Sao Paulo)",
|
||||
},
|
||||
|
|
@ -249,6 +257,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -256,6 +265,17 @@ var awsPartition = partition{
|
|||
"us-west-2": endpoint{},
|
||||
},
|
||||
},
|
||||
"api.pricing": service{
|
||||
Defaults: endpoint{
|
||||
CredentialScope: credentialScope{
|
||||
Service: "pricing",
|
||||
},
|
||||
},
|
||||
Endpoints: endpoints{
|
||||
"ap-south-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"apigateway": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
|
|
@ -268,6 +288,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -293,6 +314,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -319,6 +341,8 @@ var awsPartition = partition{
|
|||
Endpoints: endpoints{
|
||||
"ap-northeast-1": endpoint{},
|
||||
"ap-southeast-1": endpoint{},
|
||||
"ap-southeast-2": endpoint{},
|
||||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -339,6 +363,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -346,6 +371,22 @@ var awsPartition = partition{
|
|||
"us-west-2": endpoint{},
|
||||
},
|
||||
},
|
||||
"autoscaling-plans": service{
|
||||
Defaults: endpoint{
|
||||
Hostname: "autoscaling.{region}.amazonaws.com",
|
||||
Protocols: []string{"http", "https"},
|
||||
CredentialScope: credentialScope{
|
||||
Service: "autoscaling-plans",
|
||||
},
|
||||
},
|
||||
Endpoints: endpoints{
|
||||
"ap-southeast-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
"us-west-2": endpoint{},
|
||||
},
|
||||
},
|
||||
"batch": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
|
|
@ -397,6 +438,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -434,12 +476,23 @@ var awsPartition = partition{
|
|||
},
|
||||
},
|
||||
"cloudhsmv2": service{
|
||||
|
||||
Defaults: endpoint{
|
||||
CredentialScope: credentialScope{
|
||||
Service: "cloudhsm",
|
||||
},
|
||||
},
|
||||
Endpoints: endpoints{
|
||||
"eu-west-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
"us-west-2": endpoint{},
|
||||
"ap-northeast-1": endpoint{},
|
||||
"ap-south-1": endpoint{},
|
||||
"ap-southeast-1": endpoint{},
|
||||
"ap-southeast-2": endpoint{},
|
||||
"ca-central-1": endpoint{},
|
||||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
"us-west-1": endpoint{},
|
||||
"us-west-2": endpoint{},
|
||||
},
|
||||
},
|
||||
"cloudsearch": service{
|
||||
|
|
@ -469,6 +522,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -480,6 +534,7 @@ var awsPartition = partition{
|
|||
|
||||
Endpoints: endpoints{
|
||||
"ap-northeast-1": endpoint{},
|
||||
"ap-northeast-2": endpoint{},
|
||||
"ap-southeast-1": endpoint{},
|
||||
"ap-southeast-2": endpoint{},
|
||||
"ca-central-1": endpoint{},
|
||||
|
|
@ -523,6 +578,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -552,8 +608,10 @@ var awsPartition = partition{
|
|||
"codestar": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"ap-northeast-1": endpoint{},
|
||||
"ap-southeast-1": endpoint{},
|
||||
"ap-southeast-2": endpoint{},
|
||||
"ca-central-1": endpoint{},
|
||||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
|
|
@ -623,6 +681,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -646,6 +705,18 @@ var awsPartition = partition{
|
|||
"us-west-2": endpoint{},
|
||||
},
|
||||
},
|
||||
"dax": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"ap-northeast-1": endpoint{},
|
||||
"ap-south-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-west-1": endpoint{},
|
||||
"us-west-2": endpoint{},
|
||||
},
|
||||
},
|
||||
"devicefarm": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
|
|
@ -664,6 +735,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -689,6 +761,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -701,6 +774,7 @@ var awsPartition = partition{
|
|||
Endpoints: endpoints{
|
||||
"ap-northeast-1": endpoint{},
|
||||
"ap-northeast-2": endpoint{},
|
||||
"ap-south-1": endpoint{},
|
||||
"ap-southeast-1": endpoint{},
|
||||
"ap-southeast-2": endpoint{},
|
||||
"ca-central-1": endpoint{},
|
||||
|
|
@ -710,6 +784,7 @@ var awsPartition = partition{
|
|||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
"us-west-1": endpoint{},
|
||||
"us-west-2": endpoint{},
|
||||
},
|
||||
},
|
||||
|
|
@ -727,6 +802,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"local": endpoint{
|
||||
Hostname: "localhost:8000",
|
||||
Protocols: []string{"http"},
|
||||
|
|
@ -755,6 +831,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -777,12 +854,16 @@ var awsPartition = partition{
|
|||
|
||||
Endpoints: endpoints{
|
||||
"ap-northeast-1": endpoint{},
|
||||
"ap-northeast-2": endpoint{},
|
||||
"ap-south-1": endpoint{},
|
||||
"ap-southeast-1": endpoint{},
|
||||
"ap-southeast-2": endpoint{},
|
||||
"ca-central-1": endpoint{},
|
||||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
"us-west-1": endpoint{},
|
||||
|
|
@ -793,12 +874,16 @@ var awsPartition = partition{
|
|||
|
||||
Endpoints: endpoints{
|
||||
"ap-northeast-1": endpoint{},
|
||||
"ap-northeast-2": endpoint{},
|
||||
"ap-south-1": endpoint{},
|
||||
"ap-southeast-1": endpoint{},
|
||||
"ap-southeast-2": endpoint{},
|
||||
"ca-central-1": endpoint{},
|
||||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
"us-west-1": endpoint{},
|
||||
|
|
@ -817,6 +902,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -836,6 +922,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -868,6 +955,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -892,6 +980,7 @@ var awsPartition = partition{
|
|||
},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{
|
||||
SSLCommonName: "{service}.{region}.{dnsSuffix}",
|
||||
|
|
@ -944,6 +1033,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -963,6 +1053,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -974,10 +1065,13 @@ var awsPartition = partition{
|
|||
|
||||
Endpoints: endpoints{
|
||||
"ap-northeast-1": endpoint{},
|
||||
"ap-southeast-1": endpoint{},
|
||||
"ap-southeast-2": endpoint{},
|
||||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
"us-west-1": endpoint{},
|
||||
"us-west-2": endpoint{},
|
||||
},
|
||||
},
|
||||
|
|
@ -1008,11 +1102,13 @@ var awsPartition = partition{
|
|||
"ap-northeast-1": endpoint{},
|
||||
"ap-northeast-2": endpoint{},
|
||||
"ap-south-1": endpoint{},
|
||||
"ap-southeast-1": endpoint{},
|
||||
"ap-southeast-2": endpoint{},
|
||||
"ca-central-1": endpoint{},
|
||||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
"us-west-1": endpoint{},
|
||||
|
|
@ -1022,7 +1118,11 @@ var awsPartition = partition{
|
|||
"glue": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"us-east-1": endpoint{},
|
||||
"ap-northeast-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
"us-west-2": endpoint{},
|
||||
},
|
||||
},
|
||||
"greengrass": service{
|
||||
|
|
@ -1031,6 +1131,7 @@ var awsPartition = partition{
|
|||
Protocols: []string{"https"},
|
||||
},
|
||||
Endpoints: endpoints{
|
||||
"ap-northeast-1": endpoint{},
|
||||
"ap-southeast-2": endpoint{},
|
||||
"eu-central-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
|
|
@ -1078,6 +1179,7 @@ var awsPartition = partition{
|
|||
"ap-northeast-2": endpoint{},
|
||||
"ap-south-1": endpoint{},
|
||||
"ap-southeast-2": endpoint{},
|
||||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-west-1": endpoint{},
|
||||
|
|
@ -1115,6 +1217,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -1142,6 +1245,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -1161,6 +1265,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -1195,6 +1300,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -1274,6 +1380,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -1302,6 +1409,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -1343,10 +1451,21 @@ var awsPartition = partition{
|
|||
"polly": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"eu-west-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
"us-west-2": endpoint{},
|
||||
"ap-northeast-1": endpoint{},
|
||||
"ap-northeast-2": endpoint{},
|
||||
"ap-south-1": endpoint{},
|
||||
"ap-southeast-1": endpoint{},
|
||||
"ap-southeast-2": endpoint{},
|
||||
"ca-central-1": endpoint{},
|
||||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
"us-west-1": endpoint{},
|
||||
"us-west-2": endpoint{},
|
||||
},
|
||||
},
|
||||
"rds": service{
|
||||
|
|
@ -1361,6 +1480,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{
|
||||
SSLCommonName: "{service}.{dnsSuffix}",
|
||||
|
|
@ -1382,6 +1502,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -1394,6 +1515,7 @@ var awsPartition = partition{
|
|||
Endpoints: endpoints{
|
||||
"eu-west-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
"us-west-2": endpoint{},
|
||||
},
|
||||
},
|
||||
|
|
@ -1423,6 +1545,7 @@ var awsPartition = partition{
|
|||
},
|
||||
},
|
||||
Endpoints: endpoints{
|
||||
"eu-west-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
},
|
||||
},
|
||||
|
|
@ -1438,26 +1561,27 @@ var awsPartition = partition{
|
|||
},
|
||||
Endpoints: endpoints{
|
||||
"ap-northeast-1": endpoint{
|
||||
Hostname: "s3-ap-northeast-1.amazonaws.com",
|
||||
Hostname: "s3.ap-northeast-1.amazonaws.com",
|
||||
SignatureVersions: []string{"s3", "s3v4"},
|
||||
},
|
||||
"ap-northeast-2": endpoint{},
|
||||
"ap-south-1": endpoint{},
|
||||
"ap-southeast-1": endpoint{
|
||||
Hostname: "s3-ap-southeast-1.amazonaws.com",
|
||||
Hostname: "s3.ap-southeast-1.amazonaws.com",
|
||||
SignatureVersions: []string{"s3", "s3v4"},
|
||||
},
|
||||
"ap-southeast-2": endpoint{
|
||||
Hostname: "s3-ap-southeast-2.amazonaws.com",
|
||||
Hostname: "s3.ap-southeast-2.amazonaws.com",
|
||||
SignatureVersions: []string{"s3", "s3v4"},
|
||||
},
|
||||
"ca-central-1": endpoint{},
|
||||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{
|
||||
Hostname: "s3-eu-west-1.amazonaws.com",
|
||||
Hostname: "s3.eu-west-1.amazonaws.com",
|
||||
SignatureVersions: []string{"s3", "s3v4"},
|
||||
},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"s3-external-1": endpoint{
|
||||
Hostname: "s3-external-1.amazonaws.com",
|
||||
SignatureVersions: []string{"s3", "s3v4"},
|
||||
|
|
@ -1466,7 +1590,7 @@ var awsPartition = partition{
|
|||
},
|
||||
},
|
||||
"sa-east-1": endpoint{
|
||||
Hostname: "s3-sa-east-1.amazonaws.com",
|
||||
Hostname: "s3.sa-east-1.amazonaws.com",
|
||||
SignatureVersions: []string{"s3", "s3v4"},
|
||||
},
|
||||
"us-east-1": endpoint{
|
||||
|
|
@ -1475,11 +1599,11 @@ var awsPartition = partition{
|
|||
},
|
||||
"us-east-2": endpoint{},
|
||||
"us-west-1": endpoint{
|
||||
Hostname: "s3-us-west-1.amazonaws.com",
|
||||
Hostname: "s3.us-west-1.amazonaws.com",
|
||||
SignatureVersions: []string{"s3", "s3v4"},
|
||||
},
|
||||
"us-west-2": endpoint{
|
||||
Hostname: "s3-us-west-2.amazonaws.com",
|
||||
Hostname: "s3.us-west-2.amazonaws.com",
|
||||
SignatureVersions: []string{"s3", "s3v4"},
|
||||
},
|
||||
},
|
||||
|
|
@ -1507,14 +1631,18 @@ var awsPartition = partition{
|
|||
Endpoints: endpoints{
|
||||
"ap-northeast-1": endpoint{},
|
||||
"ap-northeast-2": endpoint{},
|
||||
"ap-south-1": endpoint{},
|
||||
"ap-southeast-1": endpoint{},
|
||||
"ap-southeast-2": endpoint{},
|
||||
"ca-central-1": endpoint{},
|
||||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
"us-west-1": endpoint{},
|
||||
"us-west-2": endpoint{},
|
||||
},
|
||||
},
|
||||
|
|
@ -1535,21 +1663,26 @@ var awsPartition = partition{
|
|||
"ap-northeast-2": endpoint{},
|
||||
"ap-south-1": endpoint{},
|
||||
"ap-southeast-2": endpoint{},
|
||||
"ca-central-1": endpoint{},
|
||||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
"us-west-1": endpoint{},
|
||||
"us-west-2": endpoint{},
|
||||
},
|
||||
},
|
||||
"snowball": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"ap-northeast-1": endpoint{},
|
||||
"ap-south-1": endpoint{},
|
||||
"ap-southeast-2": endpoint{},
|
||||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -1571,6 +1704,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -1593,6 +1727,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{
|
||||
SSLCommonName: "queue.{dnsSuffix}",
|
||||
|
|
@ -1614,6 +1749,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -1646,6 +1782,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -1670,6 +1807,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"local": endpoint{
|
||||
Hostname: "localhost:8000",
|
||||
Protocols: []string{"http"},
|
||||
|
|
@ -1708,6 +1846,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-1-fips": endpoint{
|
||||
|
|
@ -1757,6 +1896,7 @@ var awsPartition = partition{
|
|||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"eu-west-3": endpoint{},
|
||||
"sa-east-1": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-east-2": endpoint{},
|
||||
|
|
@ -1825,6 +1965,7 @@ var awsPartition = partition{
|
|||
"ap-southeast-2": endpoint{},
|
||||
"eu-central-1": endpoint{},
|
||||
"eu-west-1": endpoint{},
|
||||
"eu-west-2": endpoint{},
|
||||
"us-east-1": endpoint{},
|
||||
"us-west-2": endpoint{},
|
||||
},
|
||||
|
|
@ -1875,8 +2016,17 @@ var awscnPartition = partition{
|
|||
"cn-north-1": region{
|
||||
Description: "China (Beijing)",
|
||||
},
|
||||
"cn-northwest-1": region{
|
||||
Description: "China (Ningxia)",
|
||||
},
|
||||
},
|
||||
Services: services{
|
||||
"apigateway": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"application-autoscaling": service{
|
||||
Defaults: endpoint{
|
||||
Hostname: "autoscaling.{region}.amazonaws.com",
|
||||
|
|
@ -1886,7 +2036,8 @@ var awscnPartition = partition{
|
|||
},
|
||||
},
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"autoscaling": service{
|
||||
|
|
@ -1894,23 +2045,33 @@ var awscnPartition = partition{
|
|||
Protocols: []string{"http", "https"},
|
||||
},
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"cloudformation": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"cloudtrail": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"codedeploy": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"cognito-identity": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
},
|
||||
|
|
@ -1918,13 +2079,15 @@ var awscnPartition = partition{
|
|||
"config": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"directconnect": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"dynamodb": service{
|
||||
|
|
@ -1932,7 +2095,8 @@ var awscnPartition = partition{
|
|||
Protocols: []string{"http", "https"},
|
||||
},
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"ec2": service{
|
||||
|
|
@ -1940,7 +2104,8 @@ var awscnPartition = partition{
|
|||
Protocols: []string{"http", "https"},
|
||||
},
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"ec2metadata": service{
|
||||
|
|
@ -1969,13 +2134,15 @@ var awscnPartition = partition{
|
|||
"elasticache": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"elasticbeanstalk": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"elasticloadbalancing": service{
|
||||
|
|
@ -1983,7 +2150,8 @@ var awscnPartition = partition{
|
|||
Protocols: []string{"https"},
|
||||
},
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"elasticmapreduce": service{
|
||||
|
|
@ -1991,13 +2159,21 @@ var awscnPartition = partition{
|
|||
Protocols: []string{"http", "https"},
|
||||
},
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"es": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"events": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"glacier": service{
|
||||
|
|
@ -2005,7 +2181,8 @@ var awscnPartition = partition{
|
|||
Protocols: []string{"http", "https"},
|
||||
},
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"iam": service{
|
||||
|
|
@ -2033,6 +2210,13 @@ var awscnPartition = partition{
|
|||
},
|
||||
"kinesis": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"lambda": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
},
|
||||
|
|
@ -2040,7 +2224,8 @@ var awscnPartition = partition{
|
|||
"logs": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"monitoring": service{
|
||||
|
|
@ -2048,19 +2233,22 @@ var awscnPartition = partition{
|
|||
Protocols: []string{"http", "https"},
|
||||
},
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"rds": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"redshift": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"s3": service{
|
||||
|
|
@ -2068,6 +2256,13 @@ var awscnPartition = partition{
|
|||
Protocols: []string{"http", "https"},
|
||||
SignatureVersions: []string{"s3v4"},
|
||||
},
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"snowball": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
},
|
||||
|
|
@ -2077,7 +2272,8 @@ var awscnPartition = partition{
|
|||
Protocols: []string{"http", "https"},
|
||||
},
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"sqs": service{
|
||||
|
|
@ -2086,13 +2282,15 @@ var awscnPartition = partition{
|
|||
Protocols: []string{"http", "https"},
|
||||
},
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"ssm": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"storagegateway": service{
|
||||
|
|
@ -2109,19 +2307,22 @@ var awscnPartition = partition{
|
|||
},
|
||||
},
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"sts": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"swf": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-north-1": endpoint{},
|
||||
"cn-northwest-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"tagging": service{
|
||||
|
|
@ -2215,10 +2416,22 @@ var awsusgovPartition = partition{
|
|||
"us-gov-west-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"dms": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"us-gov-west-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"dynamodb": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"us-gov-west-1": endpoint{},
|
||||
"us-gov-west-1-fips": endpoint{
|
||||
Hostname: "dynamodb.us-gov-west-1.amazonaws.com",
|
||||
CredentialScope: credentialScope{
|
||||
Region: "us-gov-west-1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"ec2": service{
|
||||
|
|
@ -2238,12 +2451,24 @@ var awsusgovPartition = partition{
|
|||
},
|
||||
},
|
||||
},
|
||||
"ecs": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"us-gov-west-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"elasticache": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"us-gov-west-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"elasticbeanstalk": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
"us-gov-west-1": endpoint{},
|
||||
},
|
||||
},
|
||||
"elasticloadbalancing": service{
|
||||
|
||||
Endpoints: endpoints{
|
||||
|
|
@ -2347,7 +2572,7 @@ var awsusgovPartition = partition{
|
|||
},
|
||||
},
|
||||
"us-gov-west-1": endpoint{
|
||||
Hostname: "s3-us-gov-west-1.amazonaws.com",
|
||||
Hostname: "s3.us-gov-west-1.amazonaws.com",
|
||||
Protocols: []string{"http", "https"},
|
||||
},
|
||||
},
|
||||
|
|
@ -2395,6 +2620,12 @@ var awsusgovPartition = partition{
|
|||
},
|
||||
Endpoints: endpoints{
|
||||
"us-gov-west-1": endpoint{},
|
||||
"us-gov-west-1-fips": endpoint{
|
||||
Hostname: "dynamodb.us-gov-west-1.amazonaws.com",
|
||||
CredentialScope: credentialScope{
|
||||
Region: "us-gov-west-1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"sts": service{
|
||||
|
|
|
|||
140
vendor/github.com/aws/aws-sdk-go/aws/request/request.go
generated
vendored
140
vendor/github.com/aws/aws-sdk-go/aws/request/request.go
generated
vendored
|
|
@ -28,6 +28,10 @@ const (
|
|||
// during body reads.
|
||||
ErrCodeResponseTimeout = "ResponseTimeout"
|
||||
|
||||
// ErrCodeInvalidPresignExpire is returned when the expire time provided to
|
||||
// presign is invalid
|
||||
ErrCodeInvalidPresignExpire = "InvalidPresignExpireError"
|
||||
|
||||
// CanceledErrorCode is the error code that will be returned by an
|
||||
// API request that was canceled. Requests given a aws.Context may
|
||||
// return this error when canceled.
|
||||
|
|
@ -42,7 +46,6 @@ type Request struct {
|
|||
|
||||
Retryer
|
||||
Time time.Time
|
||||
ExpireTime time.Duration
|
||||
Operation *Operation
|
||||
HTTPRequest *http.Request
|
||||
HTTPResponse *http.Response
|
||||
|
|
@ -60,6 +63,11 @@ type Request struct {
|
|||
LastSignedAt time.Time
|
||||
DisableFollowRedirects bool
|
||||
|
||||
// A value greater than 0 instructs the request to be signed as Presigned URL
|
||||
// You should not set this field directly. Instead use Request's
|
||||
// Presign or PresignRequest methods.
|
||||
ExpireTime time.Duration
|
||||
|
||||
context aws.Context
|
||||
|
||||
built bool
|
||||
|
|
@ -104,6 +112,8 @@ func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers,
|
|||
err = awserr.New("InvalidEndpointURL", "invalid endpoint uri", err)
|
||||
}
|
||||
|
||||
SanitizeHostForHeader(httpReq)
|
||||
|
||||
r := &Request{
|
||||
Config: cfg,
|
||||
ClientInfo: clientInfo,
|
||||
|
|
@ -250,40 +260,59 @@ func (r *Request) SetReaderBody(reader io.ReadSeeker) {
|
|||
|
||||
// Presign returns the request's signed URL. Error will be returned
|
||||
// if the signing fails.
|
||||
func (r *Request) Presign(expireTime time.Duration) (string, error) {
|
||||
r.ExpireTime = expireTime
|
||||
//
|
||||
// It is invalid to create a presigned URL with a expire duration 0 or less. An
|
||||
// error is returned if expire duration is 0 or less.
|
||||
func (r *Request) Presign(expire time.Duration) (string, error) {
|
||||
r = r.copy()
|
||||
|
||||
// Presign requires all headers be hoisted. There is no way to retrieve
|
||||
// the signed headers not hoisted without this. Making the presigned URL
|
||||
// useless.
|
||||
r.NotHoist = false
|
||||
|
||||
if r.Operation.BeforePresignFn != nil {
|
||||
r = r.copy()
|
||||
err := r.Operation.BeforePresignFn(r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
r.Sign()
|
||||
if r.Error != nil {
|
||||
return "", r.Error
|
||||
}
|
||||
return r.HTTPRequest.URL.String(), nil
|
||||
u, _, err := getPresignedURL(r, expire)
|
||||
return u, err
|
||||
}
|
||||
|
||||
// PresignRequest behaves just like presign, with the addition of returning a
|
||||
// set of headers that were signed.
|
||||
//
|
||||
// It is invalid to create a presigned URL with a expire duration 0 or less. An
|
||||
// error is returned if expire duration is 0 or less.
|
||||
//
|
||||
// Returns the URL string for the API operation with signature in the query string,
|
||||
// and the HTTP headers that were included in the signature. These headers must
|
||||
// be included in any HTTP request made with the presigned URL.
|
||||
//
|
||||
// To prevent hoisting any headers to the query string set NotHoist to true on
|
||||
// this Request value prior to calling PresignRequest.
|
||||
func (r *Request) PresignRequest(expireTime time.Duration) (string, http.Header, error) {
|
||||
r.ExpireTime = expireTime
|
||||
r.Sign()
|
||||
if r.Error != nil {
|
||||
return "", nil, r.Error
|
||||
func (r *Request) PresignRequest(expire time.Duration) (string, http.Header, error) {
|
||||
r = r.copy()
|
||||
return getPresignedURL(r, expire)
|
||||
}
|
||||
|
||||
func getPresignedURL(r *Request, expire time.Duration) (string, http.Header, error) {
|
||||
if expire <= 0 {
|
||||
return "", nil, awserr.New(
|
||||
ErrCodeInvalidPresignExpire,
|
||||
"presigned URL requires an expire duration greater than 0",
|
||||
nil,
|
||||
)
|
||||
}
|
||||
|
||||
r.ExpireTime = expire
|
||||
|
||||
if r.Operation.BeforePresignFn != nil {
|
||||
if err := r.Operation.BeforePresignFn(r); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := r.Sign(); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
return r.HTTPRequest.URL.String(), r.SignedHeaderVals, nil
|
||||
}
|
||||
|
||||
|
|
@ -579,3 +608,72 @@ func shouldRetryCancel(r *Request) bool {
|
|||
errStr != "net/http: request canceled while waiting for connection")
|
||||
|
||||
}
|
||||
|
||||
// SanitizeHostForHeader removes default port from host and updates request.Host
|
||||
func SanitizeHostForHeader(r *http.Request) {
|
||||
host := getHost(r)
|
||||
port := portOnly(host)
|
||||
if port != "" && isDefaultPort(r.URL.Scheme, port) {
|
||||
r.Host = stripPort(host)
|
||||
}
|
||||
}
|
||||
|
||||
// Returns host from request
|
||||
func getHost(r *http.Request) string {
|
||||
if r.Host != "" {
|
||||
return r.Host
|
||||
}
|
||||
|
||||
return r.URL.Host
|
||||
}
|
||||
|
||||
// Hostname returns u.Host, without any port number.
|
||||
//
|
||||
// If Host is an IPv6 literal with a port number, Hostname returns the
|
||||
// IPv6 literal without the square brackets. IPv6 literals may include
|
||||
// a zone identifier.
|
||||
//
|
||||
// Copied from the Go 1.8 standard library (net/url)
|
||||
func stripPort(hostport string) string {
|
||||
colon := strings.IndexByte(hostport, ':')
|
||||
if colon == -1 {
|
||||
return hostport
|
||||
}
|
||||
if i := strings.IndexByte(hostport, ']'); i != -1 {
|
||||
return strings.TrimPrefix(hostport[:i], "[")
|
||||
}
|
||||
return hostport[:colon]
|
||||
}
|
||||
|
||||
// Port returns the port part of u.Host, without the leading colon.
|
||||
// If u.Host doesn't contain a port, Port returns an empty string.
|
||||
//
|
||||
// Copied from the Go 1.8 standard library (net/url)
|
||||
func portOnly(hostport string) string {
|
||||
colon := strings.IndexByte(hostport, ':')
|
||||
if colon == -1 {
|
||||
return ""
|
||||
}
|
||||
if i := strings.Index(hostport, "]:"); i != -1 {
|
||||
return hostport[i+len("]:"):]
|
||||
}
|
||||
if strings.Contains(hostport, "]") {
|
||||
return ""
|
||||
}
|
||||
return hostport[colon+len(":"):]
|
||||
}
|
||||
|
||||
// Returns true if the specified URI is using the standard port
|
||||
// (i.e. port 80 for HTTP URIs or 443 for HTTPS URIs)
|
||||
func isDefaultPort(scheme, port string) bool {
|
||||
if port == "" {
|
||||
return true
|
||||
}
|
||||
|
||||
lowerCaseScheme := strings.ToLower(scheme)
|
||||
if (lowerCaseScheme == "http" && port == "80") || (lowerCaseScheme == "https" && port == "443") {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
25
vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go
generated
vendored
25
vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go
generated
vendored
|
|
@ -142,13 +142,28 @@ func (r *Request) nextPageTokens() []interface{} {
|
|||
tokens := []interface{}{}
|
||||
tokenAdded := false
|
||||
for _, outToken := range r.Operation.OutputTokens {
|
||||
v, _ := awsutil.ValuesAtPath(r.Data, outToken)
|
||||
if len(v) > 0 {
|
||||
tokens = append(tokens, v[0])
|
||||
tokenAdded = true
|
||||
} else {
|
||||
vs, _ := awsutil.ValuesAtPath(r.Data, outToken)
|
||||
if len(vs) == 0 {
|
||||
tokens = append(tokens, nil)
|
||||
continue
|
||||
}
|
||||
v := vs[0]
|
||||
|
||||
switch tv := v.(type) {
|
||||
case *string:
|
||||
if len(aws.StringValue(tv)) == 0 {
|
||||
tokens = append(tokens, nil)
|
||||
continue
|
||||
}
|
||||
case string:
|
||||
if len(tv) == 0 {
|
||||
tokens = append(tokens, nil)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
tokenAdded = true
|
||||
tokens = append(tokens, v)
|
||||
}
|
||||
if !tokenAdded {
|
||||
return nil
|
||||
|
|
|
|||
5
vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go
generated
vendored
5
vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go
generated
vendored
|
|
@ -7,6 +7,9 @@ import (
|
|||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
)
|
||||
|
||||
// EnvProviderName provides a name of the provider when config is loaded from environment.
|
||||
const EnvProviderName = "EnvConfigCredentials"
|
||||
|
||||
// envConfig is a collection of environment values the SDK will read
|
||||
// setup config from. All environment values are optional. But some values
|
||||
// such as credentials require multiple values to be complete or the values
|
||||
|
|
@ -157,7 +160,7 @@ func envConfigLoad(enableSharedConfig bool) envConfig {
|
|||
if len(cfg.Creds.AccessKeyID) == 0 || len(cfg.Creds.SecretAccessKey) == 0 {
|
||||
cfg.Creds = credentials.Value{}
|
||||
} else {
|
||||
cfg.Creds.ProviderName = "EnvConfigCredentials"
|
||||
cfg.Creds.ProviderName = EnvProviderName
|
||||
}
|
||||
|
||||
regionKeys := regionEnvKeys
|
||||
|
|
|
|||
15
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go
generated
vendored
15
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go
generated
vendored
|
|
@ -268,7 +268,7 @@ type signingCtx struct {
|
|||
// "X-Amz-Content-Sha256" header with a precomputed value. The signer will
|
||||
// only compute the hash if the request header value is empty.
|
||||
func (v4 Signer) Sign(r *http.Request, body io.ReadSeeker, service, region string, signTime time.Time) (http.Header, error) {
|
||||
return v4.signWithBody(r, body, service, region, 0, signTime)
|
||||
return v4.signWithBody(r, body, service, region, 0, false, signTime)
|
||||
}
|
||||
|
||||
// Presign signs AWS v4 requests with the provided body, service name, region
|
||||
|
|
@ -302,10 +302,10 @@ func (v4 Signer) Sign(r *http.Request, body io.ReadSeeker, service, region strin
|
|||
// presigned request's signature you can set the "X-Amz-Content-Sha256"
|
||||
// HTTP header and that will be included in the request's signature.
|
||||
func (v4 Signer) Presign(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) {
|
||||
return v4.signWithBody(r, body, service, region, exp, signTime)
|
||||
return v4.signWithBody(r, body, service, region, exp, true, signTime)
|
||||
}
|
||||
|
||||
func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) {
|
||||
func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, isPresign bool, signTime time.Time) (http.Header, error) {
|
||||
currentTimeFn := v4.currentTimeFn
|
||||
if currentTimeFn == nil {
|
||||
currentTimeFn = time.Now
|
||||
|
|
@ -317,7 +317,7 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi
|
|||
Query: r.URL.Query(),
|
||||
Time: signTime,
|
||||
ExpireTime: exp,
|
||||
isPresign: exp != 0,
|
||||
isPresign: isPresign,
|
||||
ServiceName: service,
|
||||
Region: region,
|
||||
DisableURIPathEscaping: v4.DisableURIPathEscaping,
|
||||
|
|
@ -339,6 +339,7 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi
|
|||
return http.Header{}, err
|
||||
}
|
||||
|
||||
ctx.sanitizeHostForHeader()
|
||||
ctx.assignAmzQueryValues()
|
||||
ctx.build(v4.DisableHeaderHoisting)
|
||||
|
||||
|
|
@ -363,6 +364,10 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi
|
|||
return ctx.SignedHeaderVals, nil
|
||||
}
|
||||
|
||||
func (ctx *signingCtx) sanitizeHostForHeader() {
|
||||
request.SanitizeHostForHeader(ctx.Request)
|
||||
}
|
||||
|
||||
func (ctx *signingCtx) handlePresignRemoval() {
|
||||
if !ctx.isPresign {
|
||||
return
|
||||
|
|
@ -467,7 +472,7 @@ func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time
|
|||
}
|
||||
|
||||
signedHeaders, err := v4.signWithBody(req.HTTPRequest, req.GetBody(),
|
||||
name, region, req.ExpireTime, signingTime,
|
||||
name, region, req.ExpireTime, req.ExpireTime > 0, signingTime,
|
||||
)
|
||||
if err != nil {
|
||||
req.Error = err
|
||||
|
|
|
|||
2
vendor/github.com/aws/aws-sdk-go/aws/version.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go/aws/version.go
generated
vendored
|
|
@ -5,4 +5,4 @@ package aws
|
|||
const SDKName = "aws-sdk-go"
|
||||
|
||||
// SDKVersion is the version of this SDK
|
||||
const SDKVersion = "1.10.41"
|
||||
const SDKVersion = "1.12.70"
|
||||
|
|
|
|||
76
vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go
generated
vendored
Normal file
76
vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go
generated
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
package protocol
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
)
|
||||
|
||||
// EscapeMode is the mode that should be use for escaping a value
|
||||
type EscapeMode uint
|
||||
|
||||
// The modes for escaping a value before it is marshaled, and unmarshaled.
|
||||
const (
|
||||
NoEscape EscapeMode = iota
|
||||
Base64Escape
|
||||
QuotedEscape
|
||||
)
|
||||
|
||||
// EncodeJSONValue marshals the value into a JSON string, and optionally base64
|
||||
// encodes the string before returning it.
|
||||
//
|
||||
// Will panic if the escape mode is unknown.
|
||||
func EncodeJSONValue(v aws.JSONValue, escape EscapeMode) (string, error) {
|
||||
b, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
switch escape {
|
||||
case NoEscape:
|
||||
return string(b), nil
|
||||
case Base64Escape:
|
||||
return base64.StdEncoding.EncodeToString(b), nil
|
||||
case QuotedEscape:
|
||||
return strconv.Quote(string(b)), nil
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("EncodeJSONValue called with unknown EscapeMode, %v", escape))
|
||||
}
|
||||
|
||||
// DecodeJSONValue will attempt to decode the string input as a JSONValue.
|
||||
// Optionally decoding base64 the value first before JSON unmarshaling.
|
||||
//
|
||||
// Will panic if the escape mode is unknown.
|
||||
func DecodeJSONValue(v string, escape EscapeMode) (aws.JSONValue, error) {
|
||||
var b []byte
|
||||
var err error
|
||||
|
||||
switch escape {
|
||||
case NoEscape:
|
||||
b = []byte(v)
|
||||
case Base64Escape:
|
||||
b, err = base64.StdEncoding.DecodeString(v)
|
||||
case QuotedEscape:
|
||||
var u string
|
||||
u, err = strconv.Unquote(v)
|
||||
b = []byte(u)
|
||||
default:
|
||||
panic(fmt.Sprintf("DecodeJSONValue called with unknown EscapeMode, %v", escape))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m := aws.JSONValue{}
|
||||
err = json.Unmarshal(b, &m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
4
vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go
generated
vendored
4
vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go
generated
vendored
|
|
@ -121,6 +121,10 @@ func (q *queryParser) parseList(v url.Values, value reflect.Value, prefix string
|
|||
return nil
|
||||
}
|
||||
|
||||
if _, ok := value.Interface().([]byte); ok {
|
||||
return q.parseScalar(v, value, prefix, tag)
|
||||
}
|
||||
|
||||
// check for unflattened list member
|
||||
if !q.isEC2 && tag.Get("flattened") == "" {
|
||||
if listName := tag.Get("locationNameList"); listName == "" {
|
||||
|
|
|
|||
21
vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go
generated
vendored
21
vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go
generated
vendored
|
|
@ -4,7 +4,6 @@ package rest
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
|
@ -18,6 +17,7 @@ import (
|
|||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
)
|
||||
|
||||
// RFC822 returns an RFC822 formatted timestamp for AWS protocols
|
||||
|
|
@ -252,13 +252,12 @@ func EscapePath(path string, encodeSep bool) string {
|
|||
return buf.String()
|
||||
}
|
||||
|
||||
func convertType(v reflect.Value, tag reflect.StructTag) (string, error) {
|
||||
func convertType(v reflect.Value, tag reflect.StructTag) (str string, err error) {
|
||||
v = reflect.Indirect(v)
|
||||
if !v.IsValid() {
|
||||
return "", errValueNotSet
|
||||
}
|
||||
|
||||
var str string
|
||||
switch value := v.Interface().(type) {
|
||||
case string:
|
||||
str = value
|
||||
|
|
@ -273,17 +272,19 @@ func convertType(v reflect.Value, tag reflect.StructTag) (string, error) {
|
|||
case time.Time:
|
||||
str = value.UTC().Format(RFC822)
|
||||
case aws.JSONValue:
|
||||
b, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
if len(value) == 0 {
|
||||
return "", errValueNotSet
|
||||
}
|
||||
escaping := protocol.NoEscape
|
||||
if tag.Get("location") == "header" {
|
||||
str = base64.StdEncoding.EncodeToString(b)
|
||||
} else {
|
||||
str = string(b)
|
||||
escaping = protocol.Base64Escape
|
||||
}
|
||||
str, err = protocol.EncodeJSONValue(value, escaping)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("unable to encode JSONValue, %v", err)
|
||||
}
|
||||
default:
|
||||
err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type())
|
||||
err := fmt.Errorf("unsupported value for param %v (%s)", v.Interface(), v.Type())
|
||||
return "", err
|
||||
}
|
||||
return str, nil
|
||||
|
|
|
|||
14
vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go
generated
vendored
14
vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go
generated
vendored
|
|
@ -3,7 +3,6 @@ package rest
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
|
@ -16,6 +15,7 @@ import (
|
|||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
)
|
||||
|
||||
// UnmarshalHandler is a named request handler for unmarshaling rest protocol requests
|
||||
|
|
@ -204,17 +204,11 @@ func unmarshalHeader(v reflect.Value, header string, tag reflect.StructTag) erro
|
|||
}
|
||||
v.Set(reflect.ValueOf(&t))
|
||||
case aws.JSONValue:
|
||||
b := []byte(header)
|
||||
var err error
|
||||
escaping := protocol.NoEscape
|
||||
if tag.Get("location") == "header" {
|
||||
b, err = base64.StdEncoding.DecodeString(header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
escaping = protocol.Base64Escape
|
||||
}
|
||||
|
||||
m := aws.JSONValue{}
|
||||
err = json.Unmarshal(b, &m)
|
||||
m, err := protocol.DecodeJSONValue(header, escaping)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
2340
vendor/github.com/aws/aws-sdk-go/service/s3/api.go
generated
vendored
2340
vendor/github.com/aws/aws-sdk-go/service/s3/api.go
generated
vendored
File diff suppressed because it is too large
Load diff
2
vendor/github.com/aws/aws-sdk-go/service/s3/doc.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go/service/s3/doc.go
generated
vendored
|
|
@ -10,7 +10,7 @@
|
|||
//
|
||||
// Using the Client
|
||||
//
|
||||
// To Amazon Simple Storage Service with the SDK use the New function to create
|
||||
// To contact Amazon Simple Storage Service with the SDK use the New function to create
|
||||
// a new service client. With that client you can make API requests to the service.
|
||||
// These clients are safe to use concurrently.
|
||||
//
|
||||
|
|
|
|||
4
vendor/github.com/aws/aws-sdk-go/service/s3/doc_custom.go
generated
vendored
4
vendor/github.com/aws/aws-sdk-go/service/s3/doc_custom.go
generated
vendored
|
|
@ -35,7 +35,7 @@
|
|||
//
|
||||
// The s3manager package's Downloader provides concurrently downloading of Objects
|
||||
// from S3. The Downloader will write S3 Object content with an io.WriterAt.
|
||||
// Once the Downloader instance is created you can call Upload concurrently from
|
||||
// Once the Downloader instance is created you can call Download concurrently from
|
||||
// multiple goroutines safely.
|
||||
//
|
||||
// // The session the S3 Downloader will use
|
||||
|
|
@ -56,7 +56,7 @@
|
|||
// Key: aws.String(myString),
|
||||
// })
|
||||
// if err != nil {
|
||||
// return fmt.Errorf("failed to upload file, %v", err)
|
||||
// return fmt.Errorf("failed to download file, %v", err)
|
||||
// }
|
||||
// fmt.Printf("file downloaded, %d bytes\n", n)
|
||||
//
|
||||
|
|
|
|||
62
vendor/github.com/aws/aws-sdk-go/service/sts/api.go
generated
vendored
62
vendor/github.com/aws/aws-sdk-go/service/sts/api.go
generated
vendored
|
|
@ -35,7 +35,7 @@ const opAssumeRole = "AssumeRole"
|
|||
// fmt.Println(resp)
|
||||
// }
|
||||
//
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRole
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRole
|
||||
func (c *STS) AssumeRoleRequest(input *AssumeRoleInput) (req *request.Request, output *AssumeRoleOutput) {
|
||||
op := &request.Operation{
|
||||
Name: opAssumeRole,
|
||||
|
|
@ -168,7 +168,7 @@ func (c *STS) AssumeRoleRequest(input *AssumeRoleInput) (req *request.Request, o
|
|||
// and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
|
||||
// in the IAM User Guide.
|
||||
//
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRole
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRole
|
||||
func (c *STS) AssumeRole(input *AssumeRoleInput) (*AssumeRoleOutput, error) {
|
||||
req, out := c.AssumeRoleRequest(input)
|
||||
return out, req.Send()
|
||||
|
|
@ -215,7 +215,7 @@ const opAssumeRoleWithSAML = "AssumeRoleWithSAML"
|
|||
// fmt.Println(resp)
|
||||
// }
|
||||
//
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAML
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAML
|
||||
func (c *STS) AssumeRoleWithSAMLRequest(input *AssumeRoleWithSAMLInput) (req *request.Request, output *AssumeRoleWithSAMLOutput) {
|
||||
op := &request.Operation{
|
||||
Name: opAssumeRoleWithSAML,
|
||||
|
|
@ -341,7 +341,7 @@ func (c *STS) AssumeRoleWithSAMLRequest(input *AssumeRoleWithSAMLInput) (req *re
|
|||
// and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
|
||||
// in the IAM User Guide.
|
||||
//
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAML
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAML
|
||||
func (c *STS) AssumeRoleWithSAML(input *AssumeRoleWithSAMLInput) (*AssumeRoleWithSAMLOutput, error) {
|
||||
req, out := c.AssumeRoleWithSAMLRequest(input)
|
||||
return out, req.Send()
|
||||
|
|
@ -388,7 +388,7 @@ const opAssumeRoleWithWebIdentity = "AssumeRoleWithWebIdentity"
|
|||
// fmt.Println(resp)
|
||||
// }
|
||||
//
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentity
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentity
|
||||
func (c *STS) AssumeRoleWithWebIdentityRequest(input *AssumeRoleWithWebIdentityInput) (req *request.Request, output *AssumeRoleWithWebIdentityOutput) {
|
||||
op := &request.Operation{
|
||||
Name: opAssumeRoleWithWebIdentity,
|
||||
|
|
@ -543,7 +543,7 @@ func (c *STS) AssumeRoleWithWebIdentityRequest(input *AssumeRoleWithWebIdentityI
|
|||
// and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
|
||||
// in the IAM User Guide.
|
||||
//
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentity
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentity
|
||||
func (c *STS) AssumeRoleWithWebIdentity(input *AssumeRoleWithWebIdentityInput) (*AssumeRoleWithWebIdentityOutput, error) {
|
||||
req, out := c.AssumeRoleWithWebIdentityRequest(input)
|
||||
return out, req.Send()
|
||||
|
|
@ -590,7 +590,7 @@ const opDecodeAuthorizationMessage = "DecodeAuthorizationMessage"
|
|||
// fmt.Println(resp)
|
||||
// }
|
||||
//
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessage
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessage
|
||||
func (c *STS) DecodeAuthorizationMessageRequest(input *DecodeAuthorizationMessageInput) (req *request.Request, output *DecodeAuthorizationMessageOutput) {
|
||||
op := &request.Operation{
|
||||
Name: opDecodeAuthorizationMessage,
|
||||
|
|
@ -655,7 +655,7 @@ func (c *STS) DecodeAuthorizationMessageRequest(input *DecodeAuthorizationMessag
|
|||
// invalid. This can happen if the token contains invalid characters, such as
|
||||
// linebreaks.
|
||||
//
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessage
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessage
|
||||
func (c *STS) DecodeAuthorizationMessage(input *DecodeAuthorizationMessageInput) (*DecodeAuthorizationMessageOutput, error) {
|
||||
req, out := c.DecodeAuthorizationMessageRequest(input)
|
||||
return out, req.Send()
|
||||
|
|
@ -702,7 +702,7 @@ const opGetCallerIdentity = "GetCallerIdentity"
|
|||
// fmt.Println(resp)
|
||||
// }
|
||||
//
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentity
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentity
|
||||
func (c *STS) GetCallerIdentityRequest(input *GetCallerIdentityInput) (req *request.Request, output *GetCallerIdentityOutput) {
|
||||
op := &request.Operation{
|
||||
Name: opGetCallerIdentity,
|
||||
|
|
@ -730,7 +730,7 @@ func (c *STS) GetCallerIdentityRequest(input *GetCallerIdentityInput) (req *requ
|
|||
//
|
||||
// See the AWS API reference guide for AWS Security Token Service's
|
||||
// API operation GetCallerIdentity for usage and error information.
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentity
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentity
|
||||
func (c *STS) GetCallerIdentity(input *GetCallerIdentityInput) (*GetCallerIdentityOutput, error) {
|
||||
req, out := c.GetCallerIdentityRequest(input)
|
||||
return out, req.Send()
|
||||
|
|
@ -777,7 +777,7 @@ const opGetFederationToken = "GetFederationToken"
|
|||
// fmt.Println(resp)
|
||||
// }
|
||||
//
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationToken
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationToken
|
||||
func (c *STS) GetFederationTokenRequest(input *GetFederationTokenInput) (req *request.Request, output *GetFederationTokenOutput) {
|
||||
op := &request.Operation{
|
||||
Name: opGetFederationToken,
|
||||
|
|
@ -899,7 +899,7 @@ func (c *STS) GetFederationTokenRequest(input *GetFederationTokenInput) (req *re
|
|||
// and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
|
||||
// in the IAM User Guide.
|
||||
//
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationToken
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationToken
|
||||
func (c *STS) GetFederationToken(input *GetFederationTokenInput) (*GetFederationTokenOutput, error) {
|
||||
req, out := c.GetFederationTokenRequest(input)
|
||||
return out, req.Send()
|
||||
|
|
@ -946,7 +946,7 @@ const opGetSessionToken = "GetSessionToken"
|
|||
// fmt.Println(resp)
|
||||
// }
|
||||
//
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionToken
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionToken
|
||||
func (c *STS) GetSessionTokenRequest(input *GetSessionTokenInput) (req *request.Request, output *GetSessionTokenOutput) {
|
||||
op := &request.Operation{
|
||||
Name: opGetSessionToken,
|
||||
|
|
@ -1027,7 +1027,7 @@ func (c *STS) GetSessionTokenRequest(input *GetSessionTokenInput) (req *request.
|
|||
// and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
|
||||
// in the IAM User Guide.
|
||||
//
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionToken
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionToken
|
||||
func (c *STS) GetSessionToken(input *GetSessionTokenInput) (*GetSessionTokenOutput, error) {
|
||||
req, out := c.GetSessionTokenRequest(input)
|
||||
return out, req.Send()
|
||||
|
|
@ -1049,7 +1049,7 @@ func (c *STS) GetSessionTokenWithContext(ctx aws.Context, input *GetSessionToken
|
|||
return out, req.Send()
|
||||
}
|
||||
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleRequest
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleRequest
|
||||
type AssumeRoleInput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
|
|
@ -1241,7 +1241,7 @@ func (s *AssumeRoleInput) SetTokenCode(v string) *AssumeRoleInput {
|
|||
|
||||
// Contains the response to a successful AssumeRole request, including temporary
|
||||
// AWS credentials that can be used to make AWS requests.
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleResponse
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleResponse
|
||||
type AssumeRoleOutput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
|
|
@ -1295,7 +1295,7 @@ func (s *AssumeRoleOutput) SetPackedPolicySize(v int64) *AssumeRoleOutput {
|
|||
return s
|
||||
}
|
||||
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAMLRequest
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAMLRequest
|
||||
type AssumeRoleWithSAMLInput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
|
|
@ -1436,7 +1436,7 @@ func (s *AssumeRoleWithSAMLInput) SetSAMLAssertion(v string) *AssumeRoleWithSAML
|
|||
|
||||
// Contains the response to a successful AssumeRoleWithSAML request, including
|
||||
// temporary AWS credentials that can be used to make AWS requests.
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAMLResponse
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAMLResponse
|
||||
type AssumeRoleWithSAMLOutput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
|
|
@ -1548,7 +1548,7 @@ func (s *AssumeRoleWithSAMLOutput) SetSubjectType(v string) *AssumeRoleWithSAMLO
|
|||
return s
|
||||
}
|
||||
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentityRequest
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentityRequest
|
||||
type AssumeRoleWithWebIdentityInput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
|
|
@ -1711,7 +1711,7 @@ func (s *AssumeRoleWithWebIdentityInput) SetWebIdentityToken(v string) *AssumeRo
|
|||
|
||||
// Contains the response to a successful AssumeRoleWithWebIdentity request,
|
||||
// including temporary AWS credentials that can be used to make AWS requests.
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentityResponse
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentityResponse
|
||||
type AssumeRoleWithWebIdentityOutput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
|
|
@ -1804,7 +1804,7 @@ func (s *AssumeRoleWithWebIdentityOutput) SetSubjectFromWebIdentityToken(v strin
|
|||
|
||||
// The identifiers for the temporary security credentials that the operation
|
||||
// returns.
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumedRoleUser
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumedRoleUser
|
||||
type AssumedRoleUser struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
|
|
@ -1847,7 +1847,7 @@ func (s *AssumedRoleUser) SetAssumedRoleId(v string) *AssumedRoleUser {
|
|||
}
|
||||
|
||||
// AWS credentials for API authentication.
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/Credentials
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/Credentials
|
||||
type Credentials struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
|
|
@ -1906,7 +1906,7 @@ func (s *Credentials) SetSessionToken(v string) *Credentials {
|
|||
return s
|
||||
}
|
||||
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessageRequest
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessageRequest
|
||||
type DecodeAuthorizationMessageInput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
|
|
@ -1951,7 +1951,7 @@ func (s *DecodeAuthorizationMessageInput) SetEncodedMessage(v string) *DecodeAut
|
|||
// A document that contains additional information about the authorization status
|
||||
// of a request from an encoded message that is returned in response to an AWS
|
||||
// request.
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessageResponse
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessageResponse
|
||||
type DecodeAuthorizationMessageOutput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
|
|
@ -1976,7 +1976,7 @@ func (s *DecodeAuthorizationMessageOutput) SetDecodedMessage(v string) *DecodeAu
|
|||
}
|
||||
|
||||
// Identifiers for the federated user that is associated with the credentials.
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/FederatedUser
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/FederatedUser
|
||||
type FederatedUser struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
|
|
@ -2017,7 +2017,7 @@ func (s *FederatedUser) SetFederatedUserId(v string) *FederatedUser {
|
|||
return s
|
||||
}
|
||||
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentityRequest
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentityRequest
|
||||
type GetCallerIdentityInput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
|
|
@ -2034,7 +2034,7 @@ func (s GetCallerIdentityInput) GoString() string {
|
|||
|
||||
// Contains the response to a successful GetCallerIdentity request, including
|
||||
// information about the entity making the request.
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentityResponse
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentityResponse
|
||||
type GetCallerIdentityOutput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
|
|
@ -2080,7 +2080,7 @@ func (s *GetCallerIdentityOutput) SetUserId(v string) *GetCallerIdentityOutput {
|
|||
return s
|
||||
}
|
||||
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationTokenRequest
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationTokenRequest
|
||||
type GetFederationTokenInput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
|
|
@ -2189,7 +2189,7 @@ func (s *GetFederationTokenInput) SetPolicy(v string) *GetFederationTokenInput {
|
|||
|
||||
// Contains the response to a successful GetFederationToken request, including
|
||||
// temporary AWS credentials that can be used to make AWS requests.
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationTokenResponse
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationTokenResponse
|
||||
type GetFederationTokenOutput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
|
|
@ -2242,7 +2242,7 @@ func (s *GetFederationTokenOutput) SetPackedPolicySize(v int64) *GetFederationTo
|
|||
return s
|
||||
}
|
||||
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionTokenRequest
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionTokenRequest
|
||||
type GetSessionTokenInput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
|
|
@ -2327,7 +2327,7 @@ func (s *GetSessionTokenInput) SetTokenCode(v string) *GetSessionTokenInput {
|
|||
|
||||
// Contains the response to a successful GetSessionToken request, including
|
||||
// temporary AWS credentials that can be used to make AWS requests.
|
||||
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionTokenResponse
|
||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionTokenResponse
|
||||
type GetSessionTokenOutput struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
|
|
|
|||
2
vendor/github.com/aws/aws-sdk-go/service/sts/doc.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go/service/sts/doc.go
generated
vendored
|
|
@ -56,7 +56,7 @@
|
|||
//
|
||||
// Using the Client
|
||||
//
|
||||
// To AWS Security Token Service with the SDK use the New function to create
|
||||
// To contact AWS Security Token Service with the SDK use the New function to create
|
||||
// a new service client. With that client you can make API requests to the service.
|
||||
// These clients are safe to use concurrently.
|
||||
//
|
||||
|
|
|
|||
6
vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md
generated
vendored
6
vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md
generated
vendored
|
|
@ -1,5 +1,11 @@
|
|||
## `jwt-go` Version History
|
||||
|
||||
#### 3.1.0
|
||||
|
||||
* Improvements to `jwt` command line tool
|
||||
* Added `SkipClaimsValidation` option to `Parser`
|
||||
* Documentation updates
|
||||
|
||||
#### 3.0.0
|
||||
|
||||
* **Compatibility Breaking Changes**: See MIGRATION_GUIDE.md for tips on updating your code
|
||||
|
|
|
|||
3
vendor/github.com/diegomarangoni/gcscache/README.md
generated
vendored
3
vendor/github.com/diegomarangoni/gcscache/README.md
generated
vendored
|
|
@ -1,3 +0,0 @@
|
|||
# GCS Cache
|
||||
|
||||
Golang cache library that saves objects to Google Cloud Storage (GCS) for usage within [imageproxy](https://github.com/willnorris/imageproxy).
|
||||
112
vendor/github.com/diegomarangoni/gcscache/gcscache.go
generated
vendored
112
vendor/github.com/diegomarangoni/gcscache/gcscache.go
generated
vendored
|
|
@ -1,112 +0,0 @@
|
|||
package gcscache
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"cloud.google.com/go/storage"
|
||||
"golang.org/x/net/context"
|
||||
"golang.org/x/oauth2/google"
|
||||
"google.golang.org/api/option"
|
||||
)
|
||||
|
||||
type Cache struct {
|
||||
pathPrefix string
|
||||
bucket *storage.BucketHandle
|
||||
}
|
||||
|
||||
func (c *Cache) Get(key string) (resp []byte, ok bool) {
|
||||
obj := c.bucket.Object(c.url(key))
|
||||
|
||||
rdr, err := obj.NewReader(context.Background())
|
||||
if err != nil {
|
||||
return []byte{}, false
|
||||
}
|
||||
defer rdr.Close()
|
||||
|
||||
resp, err = ioutil.ReadAll(rdr)
|
||||
if err != nil {
|
||||
log.Printf("gcscache.Get failed: %s", err)
|
||||
}
|
||||
|
||||
return resp, err == nil
|
||||
}
|
||||
|
||||
func (c *Cache) Set(key string, resp []byte) {
|
||||
obj := c.bucket.Object(c.url(key))
|
||||
|
||||
contentType := http.DetectContentType(resp)
|
||||
|
||||
w := obj.NewWriter(context.Background())
|
||||
w.ContentType = contentType
|
||||
w.ObjectAttrs.ContentType = contentType
|
||||
|
||||
_, err := w.Write(resp)
|
||||
if err != nil {
|
||||
log.Printf("gcscache.Set failed: %s", err)
|
||||
}
|
||||
|
||||
err = w.Close()
|
||||
if err != nil {
|
||||
log.Printf("gcscache.Set failed: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Cache) Delete(key string) {
|
||||
obj := c.bucket.Object(c.url(key))
|
||||
|
||||
err := obj.Delete(context.Background())
|
||||
if err != nil {
|
||||
log.Printf("gcscache.Delete failed: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Cache) url(key string) string {
|
||||
key = cacheKeyToObjectKey(key)
|
||||
if strings.HasSuffix(c.pathPrefix, "/") {
|
||||
return c.pathPrefix + key
|
||||
}
|
||||
return c.pathPrefix + "/" + key
|
||||
}
|
||||
|
||||
func cacheKeyToObjectKey(key string) string {
|
||||
h := md5.New()
|
||||
io.WriteString(h, key)
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
func New(bucketURL string) *Cache {
|
||||
cfg, err := google.JWTConfigFromJSON([]byte(os.Getenv("GCP_PRIVATE_KEY")), storage.ScopeReadWrite)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ts := cfg.TokenSource(context.Background())
|
||||
opt := option.WithTokenSource(ts)
|
||||
|
||||
client, err := storage.NewClient(context.Background(), opt)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
r := regexp.MustCompile("gcs://([^/]+)(/(.+)?)?$")
|
||||
if !r.MatchString(bucketURL) {
|
||||
panic("Invalid bucket string format. Must match: gcs://bucket-name/path/prefix")
|
||||
}
|
||||
|
||||
match := r.FindStringSubmatch(bucketURL)
|
||||
|
||||
bucketName := match[1]
|
||||
pathPrefix := match[3]
|
||||
|
||||
return &Cache{
|
||||
pathPrefix: pathPrefix,
|
||||
bucket: client.Bucket(bucketName),
|
||||
}
|
||||
}
|
||||
18
vendor/github.com/disintegration/imaging/adjust.go
generated
vendored
18
vendor/github.com/disintegration/imaging/adjust.go
generated
vendored
|
|
@ -10,17 +10,17 @@ import (
|
|||
//
|
||||
// Example:
|
||||
//
|
||||
// dstImage = imaging.AdjustFunc(
|
||||
// srcImage,
|
||||
// func(c color.NRGBA) color.NRGBA {
|
||||
// // shift the red channel by 16
|
||||
// dstImage = imaging.AdjustFunc(
|
||||
// srcImage,
|
||||
// func(c color.NRGBA) color.NRGBA {
|
||||
// // shift the red channel by 16
|
||||
// r := int(c.R) + 16
|
||||
// if r > 255 {
|
||||
// r = 255
|
||||
// }
|
||||
// return color.NRGBA{uint8(r), c.G, c.B, c.A}
|
||||
// }
|
||||
// )
|
||||
// r = 255
|
||||
// }
|
||||
// return color.NRGBA{uint8(r), c.G, c.B, c.A}
|
||||
// }
|
||||
// )
|
||||
//
|
||||
func AdjustFunc(img image.Image, fn func(c color.NRGBA) color.NRGBA) *image.NRGBA {
|
||||
src := toNRGBA(img)
|
||||
|
|
|
|||
312
vendor/github.com/disintegration/imaging/clone.go
generated
vendored
Normal file
312
vendor/github.com/disintegration/imaging/clone.go
generated
vendored
Normal file
|
|
@ -0,0 +1,312 @@
|
|||
package imaging
|
||||
|
||||
import (
|
||||
"image"
|
||||
"image/color"
|
||||
)
|
||||
|
||||
// Clone returns a copy of the given image.
|
||||
func Clone(img image.Image) *image.NRGBA {
|
||||
dstBounds := img.Bounds().Sub(img.Bounds().Min)
|
||||
dst := image.NewNRGBA(dstBounds)
|
||||
|
||||
switch src := img.(type) {
|
||||
case *image.NRGBA:
|
||||
copyNRGBA(dst, src)
|
||||
case *image.NRGBA64:
|
||||
copyNRGBA64(dst, src)
|
||||
case *image.RGBA:
|
||||
copyRGBA(dst, src)
|
||||
case *image.RGBA64:
|
||||
copyRGBA64(dst, src)
|
||||
case *image.Gray:
|
||||
copyGray(dst, src)
|
||||
case *image.Gray16:
|
||||
copyGray16(dst, src)
|
||||
case *image.YCbCr:
|
||||
copyYCbCr(dst, src)
|
||||
case *image.Paletted:
|
||||
copyPaletted(dst, src)
|
||||
default:
|
||||
copyImage(dst, src)
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
func copyNRGBA(dst *image.NRGBA, src *image.NRGBA) {
|
||||
srcMinX := src.Rect.Min.X
|
||||
srcMinY := src.Rect.Min.Y
|
||||
dstW := dst.Rect.Dx()
|
||||
dstH := dst.Rect.Dy()
|
||||
rowSize := dstW * 4
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
copy(dst.Pix[di:di+rowSize], src.Pix[si:si+rowSize])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func copyNRGBA64(dst *image.NRGBA, src *image.NRGBA64) {
|
||||
srcMinX := src.Rect.Min.X
|
||||
srcMinY := src.Rect.Min.Y
|
||||
dstW := dst.Rect.Dx()
|
||||
dstH := dst.Rect.Dy()
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
dst.Pix[di+0] = src.Pix[si+0]
|
||||
dst.Pix[di+1] = src.Pix[si+2]
|
||||
dst.Pix[di+2] = src.Pix[si+4]
|
||||
dst.Pix[di+3] = src.Pix[si+6]
|
||||
di += 4
|
||||
si += 8
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func copyRGBA(dst *image.NRGBA, src *image.RGBA) {
|
||||
srcMinX := src.Rect.Min.X
|
||||
srcMinY := src.Rect.Min.Y
|
||||
dstW := dst.Rect.Dx()
|
||||
dstH := dst.Rect.Dy()
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
a := src.Pix[si+3]
|
||||
dst.Pix[di+3] = a
|
||||
|
||||
switch a {
|
||||
case 0:
|
||||
dst.Pix[di+0] = 0
|
||||
dst.Pix[di+1] = 0
|
||||
dst.Pix[di+2] = 0
|
||||
case 0xff:
|
||||
dst.Pix[di+0] = src.Pix[si+0]
|
||||
dst.Pix[di+1] = src.Pix[si+1]
|
||||
dst.Pix[di+2] = src.Pix[si+2]
|
||||
default:
|
||||
var tmp uint16
|
||||
tmp = uint16(src.Pix[si+0]) * 0xff / uint16(a)
|
||||
dst.Pix[di+0] = uint8(tmp)
|
||||
tmp = uint16(src.Pix[si+1]) * 0xff / uint16(a)
|
||||
dst.Pix[di+1] = uint8(tmp)
|
||||
tmp = uint16(src.Pix[si+2]) * 0xff / uint16(a)
|
||||
dst.Pix[di+2] = uint8(tmp)
|
||||
}
|
||||
|
||||
di += 4
|
||||
si += 4
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func copyRGBA64(dst *image.NRGBA, src *image.RGBA64) {
|
||||
srcMinX := src.Rect.Min.X
|
||||
srcMinY := src.Rect.Min.Y
|
||||
dstW := dst.Rect.Dx()
|
||||
dstH := dst.Rect.Dy()
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
a := src.Pix[si+6]
|
||||
dst.Pix[di+3] = a
|
||||
|
||||
switch a {
|
||||
case 0:
|
||||
dst.Pix[di+0] = 0
|
||||
dst.Pix[di+1] = 0
|
||||
dst.Pix[di+2] = 0
|
||||
case 0xff:
|
||||
dst.Pix[di+0] = src.Pix[si+0]
|
||||
dst.Pix[di+1] = src.Pix[si+2]
|
||||
dst.Pix[di+2] = src.Pix[si+4]
|
||||
default:
|
||||
var tmp uint16
|
||||
tmp = uint16(src.Pix[si+0]) * 0xff / uint16(a)
|
||||
dst.Pix[di+0] = uint8(tmp)
|
||||
tmp = uint16(src.Pix[si+2]) * 0xff / uint16(a)
|
||||
dst.Pix[di+1] = uint8(tmp)
|
||||
tmp = uint16(src.Pix[si+4]) * 0xff / uint16(a)
|
||||
dst.Pix[di+2] = uint8(tmp)
|
||||
}
|
||||
|
||||
di += 4
|
||||
si += 8
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func copyGray(dst *image.NRGBA, src *image.Gray) {
|
||||
srcMinX := src.Rect.Min.X
|
||||
srcMinY := src.Rect.Min.Y
|
||||
dstW := dst.Rect.Dx()
|
||||
dstH := dst.Rect.Dy()
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
c := src.Pix[si]
|
||||
dst.Pix[di+0] = c
|
||||
dst.Pix[di+1] = c
|
||||
dst.Pix[di+2] = c
|
||||
dst.Pix[di+3] = 0xff
|
||||
di += 4
|
||||
si++
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func copyGray16(dst *image.NRGBA, src *image.Gray16) {
|
||||
srcMinX := src.Rect.Min.X
|
||||
srcMinY := src.Rect.Min.Y
|
||||
dstW := dst.Rect.Dx()
|
||||
dstH := dst.Rect.Dy()
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
c := src.Pix[si]
|
||||
dst.Pix[di+0] = c
|
||||
dst.Pix[di+1] = c
|
||||
dst.Pix[di+2] = c
|
||||
dst.Pix[di+3] = 0xff
|
||||
di += 4
|
||||
si += 2
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func copyYCbCr(dst *image.NRGBA, src *image.YCbCr) {
|
||||
srcMinX := src.Rect.Min.X
|
||||
srcMinY := src.Rect.Min.Y
|
||||
dstW := dst.Rect.Dx()
|
||||
dstH := dst.Rect.Dy()
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
srcY := srcMinY + dstY
|
||||
di := dst.PixOffset(0, dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
srcX := srcMinX + dstX
|
||||
|
||||
siy := (srcY-srcMinY)*src.YStride + (srcX - srcMinX)
|
||||
|
||||
var sic int
|
||||
switch src.SubsampleRatio {
|
||||
case image.YCbCrSubsampleRatio444:
|
||||
sic = (srcY-srcMinY)*src.CStride + (srcX - srcMinX)
|
||||
case image.YCbCrSubsampleRatio422:
|
||||
sic = (srcY-srcMinY)*src.CStride + (srcX/2 - srcMinX/2)
|
||||
case image.YCbCrSubsampleRatio420:
|
||||
sic = (srcY/2-srcMinY/2)*src.CStride + (srcX/2 - srcMinX/2)
|
||||
case image.YCbCrSubsampleRatio440:
|
||||
sic = (srcY/2-srcMinY/2)*src.CStride + (srcX - srcMinX)
|
||||
default:
|
||||
sic = src.COffset(srcX, srcY)
|
||||
}
|
||||
|
||||
y := int32(src.Y[siy])
|
||||
cb := int32(src.Cb[sic]) - 128
|
||||
cr := int32(src.Cr[sic]) - 128
|
||||
|
||||
r := (y<<16 + 91881*cr + 1<<15) >> 16
|
||||
if r > 255 {
|
||||
r = 255
|
||||
} else if r < 0 {
|
||||
r = 0
|
||||
}
|
||||
|
||||
g := (y<<16 - 22554*cb - 46802*cr + 1<<15) >> 16
|
||||
if g > 255 {
|
||||
g = 255
|
||||
} else if g < 0 {
|
||||
g = 0
|
||||
}
|
||||
|
||||
b := (y<<16 + 116130*cb + 1<<15) >> 16
|
||||
if b > 255 {
|
||||
b = 255
|
||||
} else if b < 0 {
|
||||
b = 0
|
||||
}
|
||||
|
||||
dst.Pix[di+0] = uint8(r)
|
||||
dst.Pix[di+1] = uint8(g)
|
||||
dst.Pix[di+2] = uint8(b)
|
||||
dst.Pix[di+3] = 255
|
||||
|
||||
di += 4
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func copyPaletted(dst *image.NRGBA, src *image.Paletted) {
|
||||
srcMinX := src.Rect.Min.X
|
||||
srcMinY := src.Rect.Min.Y
|
||||
dstW := dst.Rect.Dx()
|
||||
dstH := dst.Rect.Dy()
|
||||
plen := len(src.Palette)
|
||||
pnew := make([]color.NRGBA, plen)
|
||||
for i := 0; i < plen; i++ {
|
||||
pnew[i] = color.NRGBAModel.Convert(src.Palette[i]).(color.NRGBA)
|
||||
}
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
c := pnew[src.Pix[si]]
|
||||
dst.Pix[di+0] = c.R
|
||||
dst.Pix[di+1] = c.G
|
||||
dst.Pix[di+2] = c.B
|
||||
dst.Pix[di+3] = c.A
|
||||
di += 4
|
||||
si++
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func copyImage(dst *image.NRGBA, src image.Image) {
|
||||
srcMinX := src.Bounds().Min.X
|
||||
srcMinY := src.Bounds().Min.Y
|
||||
dstW := dst.Bounds().Dx()
|
||||
dstH := dst.Bounds().Dy()
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
c := color.NRGBAModel.Convert(src.At(srcMinX+dstX, srcMinY+dstY)).(color.NRGBA)
|
||||
dst.Pix[di+0] = c.R
|
||||
dst.Pix[di+1] = c.G
|
||||
dst.Pix[di+2] = c.B
|
||||
dst.Pix[di+3] = c.A
|
||||
di += 4
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// toNRGBA converts any image type to *image.NRGBA with min-point at (0, 0).
|
||||
func toNRGBA(img image.Image) *image.NRGBA {
|
||||
if img, ok := img.(*image.NRGBA); ok && img.Bounds().Min.Eq(image.ZP) {
|
||||
return img
|
||||
}
|
||||
return Clone(img)
|
||||
}
|
||||
4
vendor/github.com/disintegration/imaging/effects.go
generated
vendored
4
vendor/github.com/disintegration/imaging/effects.go
generated
vendored
|
|
@ -14,7 +14,7 @@ func gaussianBlurKernel(x, sigma float64) float64 {
|
|||
//
|
||||
// Usage example:
|
||||
//
|
||||
// dstImage := imaging.Blur(srcImage, 3.5)
|
||||
// dstImage := imaging.Blur(srcImage, 3.5)
|
||||
//
|
||||
func Blur(img image.Image, sigma float64) *image.NRGBA {
|
||||
if sigma <= 0 {
|
||||
|
|
@ -138,7 +138,7 @@ func blurVertical(src *image.NRGBA, kernel []float64) *image.NRGBA {
|
|||
//
|
||||
// Usage example:
|
||||
//
|
||||
// dstImage := imaging.Sharpen(srcImage, 3.5)
|
||||
// dstImage := imaging.Sharpen(srcImage, 3.5)
|
||||
//
|
||||
func Sharpen(img image.Image, sigma float64) *image.NRGBA {
|
||||
if sigma <= 0 {
|
||||
|
|
|
|||
256
vendor/github.com/disintegration/imaging/helpers.go
generated
vendored
256
vendor/github.com/disintegration/imaging/helpers.go
generated
vendored
|
|
@ -76,8 +76,32 @@ func Open(filename string) (image.Image, error) {
|
|||
return img, err
|
||||
}
|
||||
|
||||
type encodeConfig struct {
|
||||
jpegQuality int
|
||||
}
|
||||
|
||||
var defaultEncodeConfig = encodeConfig{
|
||||
jpegQuality: 95,
|
||||
}
|
||||
|
||||
// EncodeOption sets an optional parameter for the Encode and Save functions.
|
||||
type EncodeOption func(*encodeConfig)
|
||||
|
||||
// JPEGQuality returns an EncodeOption that sets the output JPEG quality.
|
||||
// Quality ranges from 1 to 100 inclusive, higher is better. Default is 95.
|
||||
func JPEGQuality(quality int) EncodeOption {
|
||||
return func(c *encodeConfig) {
|
||||
c.jpegQuality = quality
|
||||
}
|
||||
}
|
||||
|
||||
// Encode writes the image img to w in the specified format (JPEG, PNG, GIF, TIFF or BMP).
|
||||
func Encode(w io.Writer, img image.Image, format Format) error {
|
||||
func Encode(w io.Writer, img image.Image, format Format, opts ...EncodeOption) error {
|
||||
cfg := defaultEncodeConfig
|
||||
for _, option := range opts {
|
||||
option(&cfg)
|
||||
}
|
||||
|
||||
var err error
|
||||
switch format {
|
||||
case JPEG:
|
||||
|
|
@ -92,9 +116,9 @@ func Encode(w io.Writer, img image.Image, format Format) error {
|
|||
}
|
||||
}
|
||||
if rgba != nil {
|
||||
err = jpeg.Encode(w, rgba, &jpeg.Options{Quality: 95})
|
||||
err = jpeg.Encode(w, rgba, &jpeg.Options{Quality: cfg.jpegQuality})
|
||||
} else {
|
||||
err = jpeg.Encode(w, img, &jpeg.Options{Quality: 95})
|
||||
err = jpeg.Encode(w, img, &jpeg.Options{Quality: cfg.jpegQuality})
|
||||
}
|
||||
|
||||
case PNG:
|
||||
|
|
@ -113,7 +137,16 @@ func Encode(w io.Writer, img image.Image, format Format) error {
|
|||
|
||||
// Save saves the image to file with the specified filename.
|
||||
// The format is determined from the filename extension: "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported.
|
||||
func Save(img image.Image, filename string) (err error) {
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// // Save the image as PNG.
|
||||
// err := imaging.Save(img, "out.png")
|
||||
//
|
||||
// // Save the image as JPEG with optional quality parameter set to 80.
|
||||
// err := imaging.Save(img, "out.jpg", imaging.JPEGQuality(80))
|
||||
//
|
||||
func Save(img image.Image, filename string, opts ...EncodeOption) (err error) {
|
||||
formats := map[string]Format{
|
||||
".jpg": JPEG,
|
||||
".jpeg": JPEG,
|
||||
|
|
@ -136,7 +169,7 @@ func Save(img image.Image, filename string) (err error) {
|
|||
}
|
||||
defer file.Close()
|
||||
|
||||
return Encode(file, img, f)
|
||||
return Encode(file, img, f, opts...)
|
||||
}
|
||||
|
||||
// New creates a new image with the specified width and height, and fills it with the specified color.
|
||||
|
|
@ -165,216 +198,3 @@ func New(width, height int, fillColor color.Color) *image.NRGBA {
|
|||
|
||||
return dst
|
||||
}
|
||||
|
||||
// Clone returns a copy of the given image.
|
||||
func Clone(img image.Image) *image.NRGBA {
|
||||
srcBounds := img.Bounds()
|
||||
srcMinX := srcBounds.Min.X
|
||||
srcMinY := srcBounds.Min.Y
|
||||
|
||||
dstBounds := srcBounds.Sub(srcBounds.Min)
|
||||
dstW := dstBounds.Dx()
|
||||
dstH := dstBounds.Dy()
|
||||
dst := image.NewNRGBA(dstBounds)
|
||||
|
||||
switch src := img.(type) {
|
||||
|
||||
case *image.NRGBA:
|
||||
rowSize := srcBounds.Dx() * 4
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
copy(dst.Pix[di:di+rowSize], src.Pix[si:si+rowSize])
|
||||
}
|
||||
})
|
||||
|
||||
case *image.NRGBA64:
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
dst.Pix[di+0] = src.Pix[si+0]
|
||||
dst.Pix[di+1] = src.Pix[si+2]
|
||||
dst.Pix[di+2] = src.Pix[si+4]
|
||||
dst.Pix[di+3] = src.Pix[si+6]
|
||||
di += 4
|
||||
si += 8
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
case *image.RGBA:
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
a := src.Pix[si+3]
|
||||
dst.Pix[di+3] = a
|
||||
|
||||
switch a {
|
||||
case 0:
|
||||
dst.Pix[di+0] = 0
|
||||
dst.Pix[di+1] = 0
|
||||
dst.Pix[di+2] = 0
|
||||
case 0xff:
|
||||
dst.Pix[di+0] = src.Pix[si+0]
|
||||
dst.Pix[di+1] = src.Pix[si+1]
|
||||
dst.Pix[di+2] = src.Pix[si+2]
|
||||
default:
|
||||
var tmp uint16
|
||||
tmp = uint16(src.Pix[si+0]) * 0xff / uint16(a)
|
||||
dst.Pix[di+0] = uint8(tmp)
|
||||
tmp = uint16(src.Pix[si+1]) * 0xff / uint16(a)
|
||||
dst.Pix[di+1] = uint8(tmp)
|
||||
tmp = uint16(src.Pix[si+2]) * 0xff / uint16(a)
|
||||
dst.Pix[di+2] = uint8(tmp)
|
||||
}
|
||||
|
||||
di += 4
|
||||
si += 4
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
case *image.RGBA64:
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
a := src.Pix[si+6]
|
||||
dst.Pix[di+3] = a
|
||||
|
||||
switch a {
|
||||
case 0:
|
||||
dst.Pix[di+0] = 0
|
||||
dst.Pix[di+1] = 0
|
||||
dst.Pix[di+2] = 0
|
||||
case 0xff:
|
||||
dst.Pix[di+0] = src.Pix[si+0]
|
||||
dst.Pix[di+1] = src.Pix[si+2]
|
||||
dst.Pix[di+2] = src.Pix[si+4]
|
||||
default:
|
||||
var tmp uint16
|
||||
tmp = uint16(src.Pix[si+0]) * 0xff / uint16(a)
|
||||
dst.Pix[di+0] = uint8(tmp)
|
||||
tmp = uint16(src.Pix[si+2]) * 0xff / uint16(a)
|
||||
dst.Pix[di+1] = uint8(tmp)
|
||||
tmp = uint16(src.Pix[si+4]) * 0xff / uint16(a)
|
||||
dst.Pix[di+2] = uint8(tmp)
|
||||
}
|
||||
|
||||
di += 4
|
||||
si += 8
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
case *image.Gray:
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
c := src.Pix[si]
|
||||
dst.Pix[di+0] = c
|
||||
dst.Pix[di+1] = c
|
||||
dst.Pix[di+2] = c
|
||||
dst.Pix[di+3] = 0xff
|
||||
di += 4
|
||||
si += 1
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
case *image.Gray16:
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
c := src.Pix[si]
|
||||
dst.Pix[di+0] = c
|
||||
dst.Pix[di+1] = c
|
||||
dst.Pix[di+2] = c
|
||||
dst.Pix[di+3] = 0xff
|
||||
di += 4
|
||||
si += 2
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
case *image.YCbCr:
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
srcX := srcMinX + dstX
|
||||
srcY := srcMinY + dstY
|
||||
siy := src.YOffset(srcX, srcY)
|
||||
sic := src.COffset(srcX, srcY)
|
||||
r, g, b := color.YCbCrToRGB(src.Y[siy], src.Cb[sic], src.Cr[sic])
|
||||
dst.Pix[di+0] = r
|
||||
dst.Pix[di+1] = g
|
||||
dst.Pix[di+2] = b
|
||||
dst.Pix[di+3] = 0xff
|
||||
di += 4
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
case *image.Paletted:
|
||||
plen := len(src.Palette)
|
||||
pnew := make([]color.NRGBA, plen)
|
||||
for i := 0; i < plen; i++ {
|
||||
pnew[i] = color.NRGBAModel.Convert(src.Palette[i]).(color.NRGBA)
|
||||
}
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
c := pnew[src.Pix[si]]
|
||||
dst.Pix[di+0] = c.R
|
||||
dst.Pix[di+1] = c.G
|
||||
dst.Pix[di+2] = c.B
|
||||
dst.Pix[di+3] = c.A
|
||||
di += 4
|
||||
si += 1
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
default:
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
c := color.NRGBAModel.Convert(img.At(srcMinX+dstX, srcMinY+dstY)).(color.NRGBA)
|
||||
dst.Pix[di+0] = c.R
|
||||
dst.Pix[di+1] = c.G
|
||||
dst.Pix[di+2] = c.B
|
||||
dst.Pix[di+3] = c.A
|
||||
di += 4
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// toNRGBA converts any image type to *image.NRGBA with min-point at (0, 0).
|
||||
func toNRGBA(img image.Image) *image.NRGBA {
|
||||
srcBounds := img.Bounds()
|
||||
if srcBounds.Min.X == 0 && srcBounds.Min.Y == 0 {
|
||||
if src0, ok := img.(*image.NRGBA); ok {
|
||||
return src0
|
||||
}
|
||||
}
|
||||
return Clone(img)
|
||||
}
|
||||
|
|
|
|||
2
vendor/github.com/disintegration/imaging/histogram.go
generated
vendored
2
vendor/github.com/disintegration/imaging/histogram.go
generated
vendored
|
|
@ -28,7 +28,7 @@ func Histogram(img image.Image) [256]float64 {
|
|||
g := src.Pix[i+1]
|
||||
b := src.Pix[i+2]
|
||||
|
||||
var y float32 = 0.299*float32(r) + 0.587*float32(g) + 0.114*float32(b)
|
||||
y := 0.299*float32(r) + 0.587*float32(g) + 0.114*float32(b)
|
||||
|
||||
histogram[int(y+0.5)]++
|
||||
total++
|
||||
|
|
|
|||
18
vendor/github.com/disintegration/imaging/resize.go
generated
vendored
18
vendor/github.com/disintegration/imaging/resize.go
generated
vendored
|
|
@ -19,6 +19,7 @@ func precomputeWeights(dstSize, srcSize int, filter ResampleFilter) [][]indexWei
|
|||
ru := math.Ceil(scale * filter.Support)
|
||||
|
||||
out := make([][]indexWeight, dstSize)
|
||||
tmp := make([]indexWeight, 0, dstSize*int(ru+2)*2)
|
||||
|
||||
for v := 0; v < dstSize; v++ {
|
||||
fu := (float64(v)+0.5)*du - 0.5
|
||||
|
|
@ -37,14 +38,17 @@ func precomputeWeights(dstSize, srcSize int, filter ResampleFilter) [][]indexWei
|
|||
w := filter.Kernel((float64(u) - fu) / scale)
|
||||
if w != 0 {
|
||||
sum += w
|
||||
out[v] = append(out[v], indexWeight{index: u, weight: w})
|
||||
tmp = append(tmp, indexWeight{index: u, weight: w})
|
||||
}
|
||||
}
|
||||
if sum != 0 {
|
||||
for i := range out[v] {
|
||||
out[v][i].weight /= sum
|
||||
for i := range tmp {
|
||||
tmp[i].weight /= sum
|
||||
}
|
||||
}
|
||||
|
||||
out[v] = tmp
|
||||
tmp = tmp[len(tmp):]
|
||||
}
|
||||
|
||||
return out
|
||||
|
|
@ -59,7 +63,7 @@ func precomputeWeights(dstSize, srcSize int, filter ResampleFilter) [][]indexWei
|
|||
//
|
||||
// Usage example:
|
||||
//
|
||||
// dstImage := imaging.Resize(srcImage, 800, 600, imaging.Lanczos)
|
||||
// dstImage := imaging.Resize(srcImage, 800, 600, imaging.Lanczos)
|
||||
//
|
||||
func Resize(img image.Image, width, height int, filter ResampleFilter) *image.NRGBA {
|
||||
dstW, dstH := width, height
|
||||
|
|
@ -239,7 +243,7 @@ func resizeNearest(src *image.NRGBA, width, height int) *image.NRGBA {
|
|||
//
|
||||
// Usage example:
|
||||
//
|
||||
// dstImage := imaging.Fit(srcImage, 800, 600, imaging.Lanczos)
|
||||
// dstImage := imaging.Fit(srcImage, 800, 600, imaging.Lanczos)
|
||||
//
|
||||
func Fit(img image.Image, width, height int, filter ResampleFilter) *image.NRGBA {
|
||||
maxW, maxH := width, height
|
||||
|
|
@ -284,7 +288,7 @@ func Fit(img image.Image, width, height int, filter ResampleFilter) *image.NRGBA
|
|||
//
|
||||
// Usage example:
|
||||
//
|
||||
// dstImage := imaging.Fill(srcImage, 800, 600, imaging.Center, imaging.Lanczos)
|
||||
// dstImage := imaging.Fill(srcImage, 800, 600, imaging.Center, imaging.Lanczos)
|
||||
//
|
||||
func Fill(img image.Image, width, height int, anchor Anchor, filter ResampleFilter) *image.NRGBA {
|
||||
minW, minH := width, height
|
||||
|
|
@ -326,7 +330,7 @@ func Fill(img image.Image, width, height int, anchor Anchor, filter ResampleFilt
|
|||
//
|
||||
// Usage example:
|
||||
//
|
||||
// dstImage := imaging.Thumbnail(srcImage, 100, 100, imaging.Lanczos)
|
||||
// dstImage := imaging.Thumbnail(srcImage, 100, 100, imaging.Lanczos)
|
||||
//
|
||||
func Thumbnail(img image.Image, width, height int, filter ResampleFilter) *image.NRGBA {
|
||||
return Fill(img, width, height, Center, filter)
|
||||
|
|
|
|||
8
vendor/github.com/disintegration/imaging/tools.go
generated
vendored
8
vendor/github.com/disintegration/imaging/tools.go
generated
vendored
|
|
@ -136,11 +136,11 @@ func PasteCenter(background, img image.Image) *image.NRGBA {
|
|||
//
|
||||
// Usage examples:
|
||||
//
|
||||
// // draw the sprite over the background at position (50, 50)
|
||||
// dstImage := imaging.Overlay(backgroundImage, spriteImage, image.Pt(50, 50), 1.0)
|
||||
// // draw the sprite over the background at position (50, 50)
|
||||
// dstImage := imaging.Overlay(backgroundImage, spriteImage, image.Pt(50, 50), 1.0)
|
||||
//
|
||||
// // blend two opaque images of the same size
|
||||
// dstImage := imaging.Overlay(imageOne, imageTwo, image.Pt(0, 0), 0.5)
|
||||
// // blend two opaque images of the same size
|
||||
// dstImage := imaging.Overlay(imageOne, imageTwo, image.Pt(0, 0), 0.5)
|
||||
//
|
||||
func Overlay(background, img image.Image, pos image.Point, opacity float64) *image.NRGBA {
|
||||
opacity = math.Min(math.Max(opacity, 0.0), 1.0) // check: 0.0 <= opacity <= 1.0
|
||||
|
|
|
|||
311
vendor/github.com/disintegration/imaging/transform.go
generated
vendored
311
vendor/github.com/disintegration/imaging/transform.go
generated
vendored
|
|
@ -2,92 +2,10 @@ package imaging
|
|||
|
||||
import (
|
||||
"image"
|
||||
"image/color"
|
||||
"math"
|
||||
)
|
||||
|
||||
// Rotate90 rotates the image 90 degrees counterclockwise and returns the transformed image.
|
||||
func Rotate90(img image.Image) *image.NRGBA {
|
||||
src := toNRGBA(img)
|
||||
srcW := src.Bounds().Max.X
|
||||
srcH := src.Bounds().Max.Y
|
||||
dstW := srcH
|
||||
dstH := srcW
|
||||
dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
|
||||
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
srcX := dstH - dstY - 1
|
||||
srcY := dstX
|
||||
|
||||
srcOff := srcY*src.Stride + srcX*4
|
||||
dstOff := dstY*dst.Stride + dstX*4
|
||||
|
||||
copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// Rotate180 rotates the image 180 degrees counterclockwise and returns the transformed image.
|
||||
func Rotate180(img image.Image) *image.NRGBA {
|
||||
src := toNRGBA(img)
|
||||
srcW := src.Bounds().Max.X
|
||||
srcH := src.Bounds().Max.Y
|
||||
dstW := srcW
|
||||
dstH := srcH
|
||||
dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
|
||||
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
srcX := dstW - dstX - 1
|
||||
srcY := dstH - dstY - 1
|
||||
|
||||
srcOff := srcY*src.Stride + srcX*4
|
||||
dstOff := dstY*dst.Stride + dstX*4
|
||||
|
||||
copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// Rotate270 rotates the image 270 degrees counterclockwise and returns the transformed image.
|
||||
func Rotate270(img image.Image) *image.NRGBA {
|
||||
src := toNRGBA(img)
|
||||
srcW := src.Bounds().Max.X
|
||||
srcH := src.Bounds().Max.Y
|
||||
dstW := srcH
|
||||
dstH := srcW
|
||||
dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
|
||||
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
srcX := dstY
|
||||
srcY := dstW - dstX - 1
|
||||
|
||||
srcOff := srcY*src.Stride + srcX*4
|
||||
dstOff := dstY*dst.Stride + dstX*4
|
||||
|
||||
copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// FlipH flips the image horizontally (from left to right) and returns the transformed image.
|
||||
func FlipH(img image.Image) *image.NRGBA {
|
||||
src := toNRGBA(img)
|
||||
|
|
@ -199,3 +117,228 @@ func Transverse(img image.Image) *image.NRGBA {
|
|||
|
||||
return dst
|
||||
}
|
||||
|
||||
// Rotate90 rotates the image 90 degrees counterclockwise and returns the transformed image.
|
||||
func Rotate90(img image.Image) *image.NRGBA {
|
||||
src := toNRGBA(img)
|
||||
srcW := src.Bounds().Max.X
|
||||
srcH := src.Bounds().Max.Y
|
||||
dstW := srcH
|
||||
dstH := srcW
|
||||
dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
|
||||
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
srcX := dstH - dstY - 1
|
||||
srcY := dstX
|
||||
|
||||
srcOff := srcY*src.Stride + srcX*4
|
||||
dstOff := dstY*dst.Stride + dstX*4
|
||||
|
||||
copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// Rotate180 rotates the image 180 degrees counterclockwise and returns the transformed image.
|
||||
func Rotate180(img image.Image) *image.NRGBA {
|
||||
src := toNRGBA(img)
|
||||
srcW := src.Bounds().Max.X
|
||||
srcH := src.Bounds().Max.Y
|
||||
dstW := srcW
|
||||
dstH := srcH
|
||||
dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
|
||||
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
srcX := dstW - dstX - 1
|
||||
srcY := dstH - dstY - 1
|
||||
|
||||
srcOff := srcY*src.Stride + srcX*4
|
||||
dstOff := dstY*dst.Stride + dstX*4
|
||||
|
||||
copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// Rotate270 rotates the image 270 degrees counterclockwise and returns the transformed image.
|
||||
func Rotate270(img image.Image) *image.NRGBA {
|
||||
src := toNRGBA(img)
|
||||
srcW := src.Bounds().Max.X
|
||||
srcH := src.Bounds().Max.Y
|
||||
dstW := srcH
|
||||
dstH := srcW
|
||||
dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
|
||||
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
srcX := dstY
|
||||
srcY := dstW - dstX - 1
|
||||
|
||||
srcOff := srcY*src.Stride + srcX*4
|
||||
dstOff := dstY*dst.Stride + dstX*4
|
||||
|
||||
copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// Rotate rotates an image by the given angle counter-clockwise .
|
||||
// The angle parameter is the rotation angle in degrees.
|
||||
// The bgColor parameter specifies the color of the uncovered zone after the rotation.
|
||||
func Rotate(img image.Image, angle float64, bgColor color.Color) *image.NRGBA {
|
||||
angle = angle - math.Floor(angle/360)*360
|
||||
|
||||
switch angle {
|
||||
case 0:
|
||||
return Clone(img)
|
||||
case 90:
|
||||
return Rotate90(img)
|
||||
case 180:
|
||||
return Rotate180(img)
|
||||
case 270:
|
||||
return Rotate270(img)
|
||||
}
|
||||
|
||||
src := toNRGBA(img)
|
||||
srcW := src.Bounds().Max.X
|
||||
srcH := src.Bounds().Max.Y
|
||||
dstW, dstH := rotatedSize(srcW, srcH, angle)
|
||||
dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
|
||||
|
||||
if dstW <= 0 || dstH <= 0 {
|
||||
return dst
|
||||
}
|
||||
|
||||
srcXOff := float64(srcW)/2 - 0.5
|
||||
srcYOff := float64(srcH)/2 - 0.5
|
||||
dstXOff := float64(dstW)/2 - 0.5
|
||||
dstYOff := float64(dstH)/2 - 0.5
|
||||
|
||||
bgColorNRGBA := color.NRGBAModel.Convert(bgColor).(color.NRGBA)
|
||||
sin, cos := math.Sincos(math.Pi * angle / 180)
|
||||
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
xf, yf := rotatePoint(float64(dstX)-dstXOff, float64(dstY)-dstYOff, sin, cos)
|
||||
xf, yf = xf+srcXOff, yf+srcYOff
|
||||
interpolatePoint(dst, dstX, dstY, src, xf, yf, bgColorNRGBA)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
func rotatePoint(x, y, sin, cos float64) (float64, float64) {
|
||||
return x*cos - y*sin, x*sin + y*cos
|
||||
}
|
||||
|
||||
func rotatedSize(w, h int, angle float64) (int, int) {
|
||||
if w <= 0 || h <= 0 {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
sin, cos := math.Sincos(math.Pi * angle / 180)
|
||||
x1, y1 := rotatePoint(float64(w-1), 0, sin, cos)
|
||||
x2, y2 := rotatePoint(float64(w-1), float64(h-1), sin, cos)
|
||||
x3, y3 := rotatePoint(0, float64(h-1), sin, cos)
|
||||
|
||||
minx := math.Min(x1, math.Min(x2, math.Min(x3, 0)))
|
||||
maxx := math.Max(x1, math.Max(x2, math.Max(x3, 0)))
|
||||
miny := math.Min(y1, math.Min(y2, math.Min(y3, 0)))
|
||||
maxy := math.Max(y1, math.Max(y2, math.Max(y3, 0)))
|
||||
|
||||
neww := maxx - minx + 1
|
||||
if neww-math.Floor(neww) > 0.1 {
|
||||
neww++
|
||||
}
|
||||
newh := maxy - miny + 1
|
||||
if newh-math.Floor(newh) > 0.1 {
|
||||
newh++
|
||||
}
|
||||
|
||||
return int(neww), int(newh)
|
||||
}
|
||||
|
||||
func interpolatePoint(dst *image.NRGBA, dstX, dstY int, src *image.NRGBA, xf, yf float64, bgColor color.NRGBA) {
|
||||
dstIndex := dstY*dst.Stride + dstX*4
|
||||
|
||||
x0 := int(math.Floor(xf))
|
||||
y0 := int(math.Floor(yf))
|
||||
bounds := src.Bounds()
|
||||
if !image.Pt(x0, y0).In(image.Rect(bounds.Min.X-1, bounds.Min.Y-1, bounds.Max.X, bounds.Max.Y)) {
|
||||
dst.Pix[dstIndex+0] = bgColor.R
|
||||
dst.Pix[dstIndex+1] = bgColor.G
|
||||
dst.Pix[dstIndex+2] = bgColor.B
|
||||
dst.Pix[dstIndex+3] = bgColor.A
|
||||
return
|
||||
}
|
||||
|
||||
xq := xf - float64(x0)
|
||||
yq := yf - float64(y0)
|
||||
|
||||
var pxs [4]color.NRGBA
|
||||
var cfs [4]float64
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
for j := 0; j < 2; j++ {
|
||||
k := i*2 + j
|
||||
pt := image.Pt(x0+j, y0+i)
|
||||
if pt.In(bounds) {
|
||||
l := pt.Y*src.Stride + pt.X*4
|
||||
pxs[k].R = src.Pix[l+0]
|
||||
pxs[k].G = src.Pix[l+1]
|
||||
pxs[k].B = src.Pix[l+2]
|
||||
pxs[k].A = src.Pix[l+3]
|
||||
} else {
|
||||
pxs[k] = bgColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cfs[0] = (1 - xq) * (1 - yq)
|
||||
cfs[1] = xq * (1 - yq)
|
||||
cfs[2] = (1 - xq) * yq
|
||||
cfs[3] = xq * yq
|
||||
|
||||
var r, g, b, a float64
|
||||
for i := range pxs {
|
||||
wa := float64(pxs[i].A) * cfs[i]
|
||||
r += float64(pxs[i].R) * wa
|
||||
g += float64(pxs[i].G) * wa
|
||||
b += float64(pxs[i].B) * wa
|
||||
a += wa
|
||||
}
|
||||
|
||||
if a != 0 {
|
||||
r /= a
|
||||
g /= a
|
||||
b /= a
|
||||
}
|
||||
|
||||
dst.Pix[dstIndex+0] = clamp(r)
|
||||
dst.Pix[dstIndex+1] = clamp(g)
|
||||
dst.Pix[dstIndex+2] = clamp(b)
|
||||
dst.Pix[dstIndex+3] = clamp(a)
|
||||
}
|
||||
|
|
|
|||
165
vendor/github.com/garyburd/redigo/redis/conn.go
generated
vendored
165
vendor/github.com/garyburd/redigo/redis/conn.go
generated
vendored
|
|
@ -29,9 +29,12 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
_ ConnWithTimeout = (*conn)(nil)
|
||||
)
|
||||
|
||||
// conn is the low-level implementation of Conn
|
||||
type conn struct {
|
||||
|
||||
// Shared
|
||||
mu sync.Mutex
|
||||
pending int
|
||||
|
|
@ -73,10 +76,11 @@ type DialOption struct {
|
|||
type dialOptions struct {
|
||||
readTimeout time.Duration
|
||||
writeTimeout time.Duration
|
||||
dialer *net.Dialer
|
||||
dial func(network, addr string) (net.Conn, error)
|
||||
db int
|
||||
password string
|
||||
dialTLS bool
|
||||
useTLS bool
|
||||
skipVerify bool
|
||||
tlsConfig *tls.Config
|
||||
}
|
||||
|
|
@ -95,17 +99,27 @@ func DialWriteTimeout(d time.Duration) DialOption {
|
|||
}}
|
||||
}
|
||||
|
||||
// DialConnectTimeout specifies the timeout for connecting to the Redis server.
|
||||
// DialConnectTimeout specifies the timeout for connecting to the Redis server when
|
||||
// no DialNetDial option is specified.
|
||||
func DialConnectTimeout(d time.Duration) DialOption {
|
||||
return DialOption{func(do *dialOptions) {
|
||||
dialer := net.Dialer{Timeout: d}
|
||||
do.dial = dialer.Dial
|
||||
do.dialer.Timeout = d
|
||||
}}
|
||||
}
|
||||
|
||||
// DialKeepAlive specifies the keep-alive period for TCP connections to the Redis server
|
||||
// when no DialNetDial option is specified.
|
||||
// If zero, keep-alives are not enabled. If no DialKeepAlive option is specified then
|
||||
// the default of 5 minutes is used to ensure that half-closed TCP sessions are detected.
|
||||
func DialKeepAlive(d time.Duration) DialOption {
|
||||
return DialOption{func(do *dialOptions) {
|
||||
do.dialer.KeepAlive = d
|
||||
}}
|
||||
}
|
||||
|
||||
// DialNetDial specifies a custom dial function for creating TCP
|
||||
// connections. If this option is left out, then net.Dial is
|
||||
// used. DialNetDial overrides DialConnectTimeout.
|
||||
// connections, otherwise a net.Dialer customized via the other options is used.
|
||||
// DialNetDial overrides DialConnectTimeout and DialKeepAlive.
|
||||
func DialNetDial(dial func(network, addr string) (net.Conn, error)) DialOption {
|
||||
return DialOption{func(do *dialOptions) {
|
||||
do.dial = dial
|
||||
|
|
@ -135,31 +149,49 @@ func DialTLSConfig(c *tls.Config) DialOption {
|
|||
}}
|
||||
}
|
||||
|
||||
// DialTLSSkipVerify to disable server name verification when connecting
|
||||
// over TLS. Has no effect when not dialing a TLS connection.
|
||||
// DialTLSSkipVerify disables server name verification when connecting over
|
||||
// TLS. Has no effect when not dialing a TLS connection.
|
||||
func DialTLSSkipVerify(skip bool) DialOption {
|
||||
return DialOption{func(do *dialOptions) {
|
||||
do.skipVerify = skip
|
||||
}}
|
||||
}
|
||||
|
||||
// DialUseTLS specifies whether TLS should be used when connecting to the
|
||||
// server. This option is ignore by DialURL.
|
||||
func DialUseTLS(useTLS bool) DialOption {
|
||||
return DialOption{func(do *dialOptions) {
|
||||
do.useTLS = useTLS
|
||||
}}
|
||||
}
|
||||
|
||||
// Dial connects to the Redis server at the given network and
|
||||
// address using the specified options.
|
||||
func Dial(network, address string, options ...DialOption) (Conn, error) {
|
||||
do := dialOptions{
|
||||
dial: net.Dial,
|
||||
dialer: &net.Dialer{
|
||||
KeepAlive: time.Minute * 5,
|
||||
},
|
||||
}
|
||||
for _, option := range options {
|
||||
option.f(&do)
|
||||
}
|
||||
if do.dial == nil {
|
||||
do.dial = do.dialer.Dial
|
||||
}
|
||||
|
||||
netConn, err := do.dial(network, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if do.dialTLS {
|
||||
tlsConfig := cloneTLSClientConfig(do.tlsConfig, do.skipVerify)
|
||||
if do.useTLS {
|
||||
var tlsConfig *tls.Config
|
||||
if do.tlsConfig == nil {
|
||||
tlsConfig = &tls.Config{InsecureSkipVerify: do.skipVerify}
|
||||
} else {
|
||||
tlsConfig = cloneTLSConfig(do.tlsConfig)
|
||||
}
|
||||
if tlsConfig.ServerName == "" {
|
||||
host, _, err := net.SplitHostPort(address)
|
||||
if err != nil {
|
||||
|
|
@ -202,10 +234,6 @@ func Dial(network, address string, options ...DialOption) (Conn, error) {
|
|||
return c, nil
|
||||
}
|
||||
|
||||
func dialTLS(do *dialOptions) {
|
||||
do.dialTLS = true
|
||||
}
|
||||
|
||||
var pathDBRegexp = regexp.MustCompile(`/(\d*)\z`)
|
||||
|
||||
// DialURL connects to a Redis server at the given URL using the Redis
|
||||
|
|
@ -257,9 +285,7 @@ func DialURL(rawurl string, options ...DialOption) (Conn, error) {
|
|||
return nil, fmt.Errorf("invalid database: %s", u.Path[1:])
|
||||
}
|
||||
|
||||
if u.Scheme == "rediss" {
|
||||
options = append([]DialOption{{dialTLS}}, options...)
|
||||
}
|
||||
options = append(options, DialUseTLS(u.Scheme == "rediss"))
|
||||
|
||||
return Dial("tcp", address, options...)
|
||||
}
|
||||
|
|
@ -344,43 +370,55 @@ func (c *conn) writeFloat64(n float64) error {
|
|||
return c.writeBytes(strconv.AppendFloat(c.numScratch[:0], n, 'g', -1, 64))
|
||||
}
|
||||
|
||||
func (c *conn) writeCommand(cmd string, args []interface{}) (err error) {
|
||||
func (c *conn) writeCommand(cmd string, args []interface{}) error {
|
||||
c.writeLen('*', 1+len(args))
|
||||
err = c.writeString(cmd)
|
||||
if err := c.writeString(cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, arg := range args {
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
switch arg := arg.(type) {
|
||||
case string:
|
||||
err = c.writeString(arg)
|
||||
case []byte:
|
||||
err = c.writeBytes(arg)
|
||||
case int:
|
||||
err = c.writeInt64(int64(arg))
|
||||
case int64:
|
||||
err = c.writeInt64(arg)
|
||||
case float64:
|
||||
err = c.writeFloat64(arg)
|
||||
case bool:
|
||||
if arg {
|
||||
err = c.writeString("1")
|
||||
} else {
|
||||
err = c.writeString("0")
|
||||
}
|
||||
case nil:
|
||||
err = c.writeString("")
|
||||
case Argument:
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprint(&buf, arg.RedisArg())
|
||||
err = c.writeBytes(buf.Bytes())
|
||||
default:
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprint(&buf, arg)
|
||||
err = c.writeBytes(buf.Bytes())
|
||||
if err := c.writeArg(arg, true); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *conn) writeArg(arg interface{}, argumentTypeOK bool) (err error) {
|
||||
switch arg := arg.(type) {
|
||||
case string:
|
||||
return c.writeString(arg)
|
||||
case []byte:
|
||||
return c.writeBytes(arg)
|
||||
case int:
|
||||
return c.writeInt64(int64(arg))
|
||||
case int64:
|
||||
return c.writeInt64(arg)
|
||||
case float64:
|
||||
return c.writeFloat64(arg)
|
||||
case bool:
|
||||
if arg {
|
||||
return c.writeString("1")
|
||||
} else {
|
||||
return c.writeString("0")
|
||||
}
|
||||
case nil:
|
||||
return c.writeString("")
|
||||
case Argument:
|
||||
if argumentTypeOK {
|
||||
return c.writeArg(arg.RedisArg(), false)
|
||||
}
|
||||
// See comment in default clause below.
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprint(&buf, arg)
|
||||
return c.writeBytes(buf.Bytes())
|
||||
default:
|
||||
// This default clause is intended to handle builtin numeric types.
|
||||
// The function should return an error for other types, but this is not
|
||||
// done for compatibility with previous versions of the package.
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprint(&buf, arg)
|
||||
return c.writeBytes(buf.Bytes())
|
||||
}
|
||||
}
|
||||
|
||||
type protocolError string
|
||||
|
|
@ -542,10 +580,17 @@ func (c *conn) Flush() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *conn) Receive() (reply interface{}, err error) {
|
||||
if c.readTimeout != 0 {
|
||||
c.conn.SetReadDeadline(time.Now().Add(c.readTimeout))
|
||||
func (c *conn) Receive() (interface{}, error) {
|
||||
return c.ReceiveWithTimeout(c.readTimeout)
|
||||
}
|
||||
|
||||
func (c *conn) ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error) {
|
||||
var deadline time.Time
|
||||
if timeout != 0 {
|
||||
deadline = time.Now().Add(timeout)
|
||||
}
|
||||
c.conn.SetReadDeadline(deadline)
|
||||
|
||||
if reply, err = c.readReply(); err != nil {
|
||||
return nil, c.fatal(err)
|
||||
}
|
||||
|
|
@ -568,6 +613,10 @@ func (c *conn) Receive() (reply interface{}, err error) {
|
|||
}
|
||||
|
||||
func (c *conn) Do(cmd string, args ...interface{}) (interface{}, error) {
|
||||
return c.DoWithTimeout(c.readTimeout, cmd, args...)
|
||||
}
|
||||
|
||||
func (c *conn) DoWithTimeout(readTimeout time.Duration, cmd string, args ...interface{}) (interface{}, error) {
|
||||
c.mu.Lock()
|
||||
pending := c.pending
|
||||
c.pending = 0
|
||||
|
|
@ -591,9 +640,11 @@ func (c *conn) Do(cmd string, args ...interface{}) (interface{}, error) {
|
|||
return nil, c.fatal(err)
|
||||
}
|
||||
|
||||
if c.readTimeout != 0 {
|
||||
c.conn.SetReadDeadline(time.Now().Add(c.readTimeout))
|
||||
var deadline time.Time
|
||||
if readTimeout != 0 {
|
||||
deadline = time.Now().Add(readTimeout)
|
||||
}
|
||||
c.conn.SetReadDeadline(deadline)
|
||||
|
||||
if cmd == "" {
|
||||
reply := make([]interface{}, pending)
|
||||
|
|
|
|||
4
vendor/github.com/garyburd/redigo/redis/doc.go
generated
vendored
4
vendor/github.com/garyburd/redigo/redis/doc.go
generated
vendored
|
|
@ -38,7 +38,7 @@
|
|||
//
|
||||
// n, err := conn.Do("APPEND", "key", "value")
|
||||
//
|
||||
// The Do method converts command arguments to binary strings for transmission
|
||||
// The Do method converts command arguments to bulk strings for transmission
|
||||
// to the server as follows:
|
||||
//
|
||||
// Go Type Conversion
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
// float64 strconv.FormatFloat(v, 'g', -1, 64)
|
||||
// bool true -> "1", false -> "0"
|
||||
// nil ""
|
||||
// all other types fmt.Print(v)
|
||||
// all other types fmt.Fprint(w, v)
|
||||
//
|
||||
// Redis command reply types are represented using the following Go types:
|
||||
//
|
||||
|
|
|
|||
|
|
@ -4,11 +4,7 @@ package redis
|
|||
|
||||
import "crypto/tls"
|
||||
|
||||
// similar cloneTLSClientConfig in the stdlib, but also honor skipVerify for the nil case
|
||||
func cloneTLSClientConfig(cfg *tls.Config, skipVerify bool) *tls.Config {
|
||||
if cfg == nil {
|
||||
return &tls.Config{InsecureSkipVerify: skipVerify}
|
||||
}
|
||||
func cloneTLSConfig(cfg *tls.Config) *tls.Config {
|
||||
return &tls.Config{
|
||||
Rand: cfg.Rand,
|
||||
Time: cfg.Time,
|
||||
8
vendor/github.com/garyburd/redigo/redis/go17.go
generated
vendored
8
vendor/github.com/garyburd/redigo/redis/go17.go
generated
vendored
|
|
@ -1,14 +1,10 @@
|
|||
// +build go1.7
|
||||
// +build go1.7,!go1.8
|
||||
|
||||
package redis
|
||||
|
||||
import "crypto/tls"
|
||||
|
||||
// similar cloneTLSClientConfig in the stdlib, but also honor skipVerify for the nil case
|
||||
func cloneTLSClientConfig(cfg *tls.Config, skipVerify bool) *tls.Config {
|
||||
if cfg == nil {
|
||||
return &tls.Config{InsecureSkipVerify: skipVerify}
|
||||
}
|
||||
func cloneTLSConfig(cfg *tls.Config) *tls.Config {
|
||||
return &tls.Config{
|
||||
Rand: cfg.Rand,
|
||||
Time: cfg.Time,
|
||||
|
|
|
|||
9
vendor/github.com/garyburd/redigo/redis/go18.go
generated
vendored
Normal file
9
vendor/github.com/garyburd/redigo/redis/go18.go
generated
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
// +build go1.8
|
||||
|
||||
package redis
|
||||
|
||||
import "crypto/tls"
|
||||
|
||||
func cloneTLSConfig(cfg *tls.Config) *tls.Config {
|
||||
return cfg.Clone()
|
||||
}
|
||||
17
vendor/github.com/garyburd/redigo/redis/log.go
generated
vendored
17
vendor/github.com/garyburd/redigo/redis/log.go
generated
vendored
|
|
@ -18,6 +18,11 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
_ ConnWithTimeout = (*loggingConn)(nil)
|
||||
)
|
||||
|
||||
// NewLoggingConn returns a logging wrapper around a connection.
|
||||
|
|
@ -104,6 +109,12 @@ func (c *loggingConn) Do(commandName string, args ...interface{}) (interface{},
|
|||
return reply, err
|
||||
}
|
||||
|
||||
func (c *loggingConn) DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (interface{}, error) {
|
||||
reply, err := DoWithTimeout(c.Conn, timeout, commandName, args...)
|
||||
c.print("DoWithTimeout", commandName, args, reply, err)
|
||||
return reply, err
|
||||
}
|
||||
|
||||
func (c *loggingConn) Send(commandName string, args ...interface{}) error {
|
||||
err := c.Conn.Send(commandName, args...)
|
||||
c.print("Send", commandName, args, nil, err)
|
||||
|
|
@ -115,3 +126,9 @@ func (c *loggingConn) Receive() (interface{}, error) {
|
|||
c.print("Receive", "", nil, reply, err)
|
||||
return reply, err
|
||||
}
|
||||
|
||||
func (c *loggingConn) ReceiveWithTimeout(timeout time.Duration) (interface{}, error) {
|
||||
reply, err := ReceiveWithTimeout(c.Conn, timeout)
|
||||
c.print("ReceiveWithTimeout", "", nil, reply, err)
|
||||
return reply, err
|
||||
}
|
||||
|
|
|
|||
61
vendor/github.com/garyburd/redigo/redis/pool.go
generated
vendored
61
vendor/github.com/garyburd/redigo/redis/pool.go
generated
vendored
|
|
@ -28,6 +28,11 @@ import (
|
|||
"github.com/garyburd/redigo/internal"
|
||||
)
|
||||
|
||||
var (
|
||||
_ ConnWithTimeout = (*pooledConnection)(nil)
|
||||
_ ConnWithTimeout = (*errorConnection)(nil)
|
||||
)
|
||||
|
||||
var nowFunc = time.Now // for testing
|
||||
|
||||
// ErrPoolExhausted is returned from a pool connection method (Do, Send,
|
||||
|
|
@ -96,7 +101,7 @@ var (
|
|||
// return nil, err
|
||||
// }
|
||||
// return c, nil
|
||||
// }
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// Use the TestOnBorrow function to check the health of an idle connection
|
||||
|
|
@ -115,7 +120,6 @@ var (
|
|||
// }
|
||||
//
|
||||
type Pool struct {
|
||||
|
||||
// Dial is an application supplied function for creating and configuring a
|
||||
// connection.
|
||||
//
|
||||
|
|
@ -181,6 +185,26 @@ func (p *Pool) Get() Conn {
|
|||
return &pooledConnection{p: p, c: c}
|
||||
}
|
||||
|
||||
// PoolStats contains pool statistics.
|
||||
type PoolStats struct {
|
||||
// ActiveCount is the number of connections in the pool. The count includes idle connections and connections in use.
|
||||
ActiveCount int
|
||||
// IdleCount is the number of idle connections in the pool.
|
||||
IdleCount int
|
||||
}
|
||||
|
||||
// Stats returns pool's statistics.
|
||||
func (p *Pool) Stats() PoolStats {
|
||||
p.mu.Lock()
|
||||
stats := PoolStats{
|
||||
ActiveCount: p.active,
|
||||
IdleCount: p.idle.Len(),
|
||||
}
|
||||
p.mu.Unlock()
|
||||
|
||||
return stats
|
||||
}
|
||||
|
||||
// ActiveCount returns the number of connections in the pool. The count includes idle connections and connections in use.
|
||||
func (p *Pool) ActiveCount() int {
|
||||
p.mu.Lock()
|
||||
|
|
@ -249,7 +273,6 @@ func (p *Pool) get() (Conn, error) {
|
|||
}
|
||||
|
||||
for {
|
||||
|
||||
// Get idle connection.
|
||||
|
||||
for i, n := 0, p.idle.Len(); i < n; i++ {
|
||||
|
|
@ -400,6 +423,16 @@ func (pc *pooledConnection) Do(commandName string, args ...interface{}) (reply i
|
|||
return pc.c.Do(commandName, args...)
|
||||
}
|
||||
|
||||
func (pc *pooledConnection) DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (reply interface{}, err error) {
|
||||
cwt, ok := pc.c.(ConnWithTimeout)
|
||||
if !ok {
|
||||
return nil, errTimeoutNotSupported
|
||||
}
|
||||
ci := internal.LookupCommandInfo(commandName)
|
||||
pc.state = (pc.state | ci.Set) &^ ci.Clear
|
||||
return cwt.DoWithTimeout(timeout, commandName, args...)
|
||||
}
|
||||
|
||||
func (pc *pooledConnection) Send(commandName string, args ...interface{}) error {
|
||||
ci := internal.LookupCommandInfo(commandName)
|
||||
pc.state = (pc.state | ci.Set) &^ ci.Clear
|
||||
|
|
@ -414,11 +447,23 @@ func (pc *pooledConnection) Receive() (reply interface{}, err error) {
|
|||
return pc.c.Receive()
|
||||
}
|
||||
|
||||
func (pc *pooledConnection) ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error) {
|
||||
cwt, ok := pc.c.(ConnWithTimeout)
|
||||
if !ok {
|
||||
return nil, errTimeoutNotSupported
|
||||
}
|
||||
return cwt.ReceiveWithTimeout(timeout)
|
||||
}
|
||||
|
||||
type errorConnection struct{ err error }
|
||||
|
||||
func (ec errorConnection) Do(string, ...interface{}) (interface{}, error) { return nil, ec.err }
|
||||
func (ec errorConnection) Send(string, ...interface{}) error { return ec.err }
|
||||
func (ec errorConnection) Err() error { return ec.err }
|
||||
func (ec errorConnection) Close() error { return ec.err }
|
||||
func (ec errorConnection) Flush() error { return ec.err }
|
||||
func (ec errorConnection) Receive() (interface{}, error) { return nil, ec.err }
|
||||
func (ec errorConnection) DoWithTimeout(time.Duration, string, ...interface{}) (interface{}, error) {
|
||||
return nil, ec.err
|
||||
}
|
||||
func (ec errorConnection) Send(string, ...interface{}) error { return ec.err }
|
||||
func (ec errorConnection) Err() error { return ec.err }
|
||||
func (ec errorConnection) Close() error { return nil }
|
||||
func (ec errorConnection) Flush() error { return ec.err }
|
||||
func (ec errorConnection) Receive() (interface{}, error) { return nil, ec.err }
|
||||
func (ec errorConnection) ReceiveWithTimeout(time.Duration) (interface{}, error) { return nil, ec.err }
|
||||
|
|
|
|||
20
vendor/github.com/garyburd/redigo/redis/pubsub.go
generated
vendored
20
vendor/github.com/garyburd/redigo/redis/pubsub.go
generated
vendored
|
|
@ -14,11 +14,13 @@
|
|||
|
||||
package redis
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Subscription represents a subscribe or unsubscribe notification.
|
||||
type Subscription struct {
|
||||
|
||||
// Kind is "subscribe", "unsubscribe", "psubscribe" or "punsubscribe"
|
||||
Kind string
|
||||
|
||||
|
|
@ -31,7 +33,6 @@ type Subscription struct {
|
|||
|
||||
// Message represents a message notification.
|
||||
type Message struct {
|
||||
|
||||
// The originating channel.
|
||||
Channel string
|
||||
|
||||
|
|
@ -41,7 +42,6 @@ type Message struct {
|
|||
|
||||
// PMessage represents a pmessage notification.
|
||||
type PMessage struct {
|
||||
|
||||
// The matched pattern.
|
||||
Pattern string
|
||||
|
||||
|
|
@ -106,7 +106,17 @@ func (c PubSubConn) Ping(data string) error {
|
|||
// or error. The return value is intended to be used directly in a type switch
|
||||
// as illustrated in the PubSubConn example.
|
||||
func (c PubSubConn) Receive() interface{} {
|
||||
reply, err := Values(c.Conn.Receive())
|
||||
return c.receiveInternal(c.Conn.Receive())
|
||||
}
|
||||
|
||||
// ReceiveWithTimeout is like Receive, but it allows the application to
|
||||
// override the connection's default timeout.
|
||||
func (c PubSubConn) ReceiveWithTimeout(timeout time.Duration) interface{} {
|
||||
return c.receiveInternal(ReceiveWithTimeout(c.Conn, timeout))
|
||||
}
|
||||
|
||||
func (c PubSubConn) receiveInternal(replyArg interface{}, errArg error) interface{} {
|
||||
reply, err := Values(replyArg, errArg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
72
vendor/github.com/garyburd/redigo/redis/redis.go
generated
vendored
72
vendor/github.com/garyburd/redigo/redis/redis.go
generated
vendored
|
|
@ -14,6 +14,11 @@
|
|||
|
||||
package redis
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Error represents an error returned in a command reply.
|
||||
type Error string
|
||||
|
||||
|
|
@ -40,20 +45,73 @@ type Conn interface {
|
|||
Receive() (reply interface{}, err error)
|
||||
}
|
||||
|
||||
// Argument is implemented by types which want to control how their value is
|
||||
// interpreted when used as an argument to a redis command.
|
||||
// Argument is the interface implemented by an object which wants to control how
|
||||
// the object is converted to Redis bulk strings.
|
||||
type Argument interface {
|
||||
// RedisArg returns the interface that represents the value to be used
|
||||
// in redis commands.
|
||||
// RedisArg returns a value to be encoded as a bulk string per the
|
||||
// conversions listed in the section 'Executing Commands'.
|
||||
// Implementations should typically return a []byte or string.
|
||||
RedisArg() interface{}
|
||||
}
|
||||
|
||||
// Scanner is implemented by types which want to control how their value is
|
||||
// interpreted when read from redis.
|
||||
// Scanner is implemented by an object which wants to control its value is
|
||||
// interpreted when read from Redis.
|
||||
type Scanner interface {
|
||||
// RedisScan assigns a value from a redis value.
|
||||
// RedisScan assigns a value from a Redis value. The argument src is one of
|
||||
// the reply types listed in the section `Executing Commands`.
|
||||
//
|
||||
// An error should be returned if the value cannot be stored without
|
||||
// loss of information.
|
||||
RedisScan(src interface{}) error
|
||||
}
|
||||
|
||||
// ConnWithTimeout is an optional interface that allows the caller to override
|
||||
// a connection's default read timeout. This interface is useful for executing
|
||||
// the BLPOP, BRPOP, BRPOPLPUSH, XREAD and other commands that block at the
|
||||
// server.
|
||||
//
|
||||
// A connection's default read timeout is set with the DialReadTimeout dial
|
||||
// option. Applications should rely on the default timeout for commands that do
|
||||
// not block at the server.
|
||||
//
|
||||
// All of the Conn implementations in this package satisfy the ConnWithTimeout
|
||||
// interface.
|
||||
//
|
||||
// Use the DoWithTimeout and ReceiveWithTimeout helper functions to simplify
|
||||
// use of this interface.
|
||||
type ConnWithTimeout interface {
|
||||
Conn
|
||||
|
||||
// Do sends a command to the server and returns the received reply.
|
||||
// The timeout overrides the read timeout set when dialing the
|
||||
// connection.
|
||||
DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (reply interface{}, err error)
|
||||
|
||||
// Receive receives a single reply from the Redis server. The timeout
|
||||
// overrides the read timeout set when dialing the connection.
|
||||
ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error)
|
||||
}
|
||||
|
||||
var errTimeoutNotSupported = errors.New("redis: connection does not support ConnWithTimeout")
|
||||
|
||||
// DoWithTimeout executes a Redis command with the specified read timeout. If
|
||||
// the connection does not satisfy the ConnWithTimeout interface, then an error
|
||||
// is returned.
|
||||
func DoWithTimeout(c Conn, timeout time.Duration, cmd string, args ...interface{}) (interface{}, error) {
|
||||
cwt, ok := c.(ConnWithTimeout)
|
||||
if !ok {
|
||||
return nil, errTimeoutNotSupported
|
||||
}
|
||||
return cwt.DoWithTimeout(timeout, cmd, args...)
|
||||
}
|
||||
|
||||
// ReceiveWithTimeout receives a reply with the specified read timeout. If the
|
||||
// connection does not satisfy the ConnWithTimeout interface, then an error is
|
||||
// returned.
|
||||
func ReceiveWithTimeout(c Conn, timeout time.Duration) (interface{}, error) {
|
||||
cwt, ok := c.(ConnWithTimeout)
|
||||
if !ok {
|
||||
return nil, errTimeoutNotSupported
|
||||
}
|
||||
return cwt.ReceiveWithTimeout(timeout)
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue