aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/Azure/azure-pipeline-go
diff options
context:
space:
mode:
authorPéter Szilágyi <peterke@gmail.com>2018-07-25 22:51:24 +0800
committerPéter Szilágyi <peterke@gmail.com>2018-07-25 23:04:43 +0800
commit6b232ce3252c6823ac84cd3d2256340f981cd387 (patch)
tree78ec24d6836fb981addafbf0013c40be0568f0a8 /vendor/github.com/Azure/azure-pipeline-go
parent7abedf9bbb725da8d610762d051af43085be1cda (diff)
downloadgo-tangerine-6b232ce3252c6823ac84cd3d2256340f981cd387.tar
go-tangerine-6b232ce3252c6823ac84cd3d2256340f981cd387.tar.gz
go-tangerine-6b232ce3252c6823ac84cd3d2256340f981cd387.tar.bz2
go-tangerine-6b232ce3252c6823ac84cd3d2256340f981cd387.tar.lz
go-tangerine-6b232ce3252c6823ac84cd3d2256340f981cd387.tar.xz
go-tangerine-6b232ce3252c6823ac84cd3d2256340f981cd387.tar.zst
go-tangerine-6b232ce3252c6823ac84cd3d2256340f981cd387.zip
internal, vendor: update Azure blobstore API
Diffstat (limited to 'vendor/github.com/Azure/azure-pipeline-go')
-rw-r--r--vendor/github.com/Azure/azure-pipeline-go/LICENSE21
-rwxr-xr-xvendor/github.com/Azure/azure-pipeline-go/pipeline/core.go255
-rwxr-xr-xvendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_syslog.go33
-rwxr-xr-xvendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_windows.go61
-rwxr-xr-xvendor/github.com/Azure/azure-pipeline-go/pipeline/doc.go161
-rwxr-xr-xvendor/github.com/Azure/azure-pipeline-go/pipeline/error.go121
-rwxr-xr-xvendor/github.com/Azure/azure-pipeline-go/pipeline/progress.go82
-rwxr-xr-xvendor/github.com/Azure/azure-pipeline-go/pipeline/request.go147
-rwxr-xr-xvendor/github.com/Azure/azure-pipeline-go/pipeline/response.go74
-rw-r--r--vendor/github.com/Azure/azure-pipeline-go/pipeline/version.go9
10 files changed, 964 insertions, 0 deletions
diff --git a/vendor/github.com/Azure/azure-pipeline-go/LICENSE b/vendor/github.com/Azure/azure-pipeline-go/LICENSE
new file mode 100644
index 000000000..d1ca00f20
--- /dev/null
+++ b/vendor/github.com/Azure/azure-pipeline-go/LICENSE
@@ -0,0 +1,21 @@
+ MIT License
+
+ Copyright (c) Microsoft Corporation. All rights reserved.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE \ No newline at end of file
diff --git a/vendor/github.com/Azure/azure-pipeline-go/pipeline/core.go b/vendor/github.com/Azure/azure-pipeline-go/pipeline/core.go
new file mode 100755
index 000000000..0dde81d72
--- /dev/null
+++ b/vendor/github.com/Azure/azure-pipeline-go/pipeline/core.go
@@ -0,0 +1,255 @@
+package pipeline
+
+import (
+ "context"
+ "net"
+ "net/http"
+ "os"
+ "time"
+)
+
+// The Factory interface represents an object that can create its Policy object. Each HTTP request sent
+// requires that this Factory create a new instance of its Policy object.
+type Factory interface {
+ New(next Policy, po *PolicyOptions) Policy
+}
+
+// FactoryFunc is an adapter that allows the use of an ordinary function as a Factory interface.
+type FactoryFunc func(next Policy, po *PolicyOptions) PolicyFunc
+
+// New calls f(next,po).
+func (f FactoryFunc) New(next Policy, po *PolicyOptions) Policy {
+ return f(next, po)
+}
+
+// The Policy interface represents a mutable Policy object created by a Factory. The object can mutate/process
+// the HTTP request and then forward it on to the next Policy object in the linked-list. The returned
+// Response goes backward through the linked-list for additional processing.
+// NOTE: Request is passed by value so changes do not change the caller's version of
+// the request. However, Request has some fields that reference mutable objects (not strings).
+// These references are copied; a deep copy is not performed. Specifically, this means that
+// you should avoid modifying the objects referred to by these fields: URL, Header, Body,
+// GetBody, TransferEncoding, Form, MultipartForm, Trailer, TLS, Cancel, and Response.
+type Policy interface {
+ Do(ctx context.Context, request Request) (Response, error)
+}
+
+// PolicyFunc is an adapter that allows the use of an ordinary function as a Policy interface.
+type PolicyFunc func(ctx context.Context, request Request) (Response, error)
+
+// Do calls f(ctx, request).
+func (f PolicyFunc) Do(ctx context.Context, request Request) (Response, error) {
+ return f(ctx, request)
+}
+
+// Options configures a Pipeline's behavior.
+type Options struct {
+ HTTPSender Factory // If sender is nil, then the pipeline's default client is used to send the HTTP requests.
+ Log LogOptions
+}
+
+// LogLevel tells a logger the minimum level to log. When code reports a log entry,
+// the LogLevel indicates the level of the log entry. The logger only records entries
+// whose level is at least the level it was told to log. See the Log* constants.
+// For example, if a logger is configured with LogError, then LogError, LogPanic,
+// and LogFatal entries will be logged; lower level entries are ignored.
+type LogLevel uint32
+
+const (
+ // LogNone tells a logger not to log any entries passed to it.
+ LogNone LogLevel = iota
+
+ // LogFatal tells a logger to log all LogFatal entries passed to it.
+ LogFatal
+
+ // LogPanic tells a logger to log all LogPanic and LogFatal entries passed to it.
+ LogPanic
+
+ // LogError tells a logger to log all LogError, LogPanic and LogFatal entries passed to it.
+ LogError
+
+ // LogWarning tells a logger to log all LogWarning, LogError, LogPanic and LogFatal entries passed to it.
+ LogWarning
+
+ // LogInfo tells a logger to log all LogInfo, LogWarning, LogError, LogPanic and LogFatal entries passed to it.
+ LogInfo
+
+ // LogDebug tells a logger to log all LogDebug, LogInfo, LogWarning, LogError, LogPanic and LogFatal entries passed to it.
+ LogDebug
+)
+
+// LogOptions configures the pipeline's logging mechanism & level filtering.
+type LogOptions struct {
+ Log func(level LogLevel, message string)
+
+ // ShouldLog is called periodically allowing you to return whether the specified LogLevel should be logged or not.
+ // An application can return different values over the its lifetime; this allows the application to dynamically
+ // alter what is logged. NOTE: This method can be called by multiple goroutines simultaneously so make sure
+ // you implement it in a goroutine-safe way. If nil, nothing is logged (the equivalent of returning LogNone).
+ // Usually, the function will be implemented simply like this: return level <= LogWarning
+ ShouldLog func(level LogLevel) bool
+}
+
+type pipeline struct {
+ factories []Factory
+ options Options
+}
+
+// The Pipeline interface represents an ordered list of Factory objects and an object implementing the HTTPSender interface.
+// You construct a Pipeline by calling the pipeline.NewPipeline function. To send an HTTP request, call pipeline.NewRequest
+// and then call Pipeline's Do method passing a context, the request, and a method-specific Factory (or nil). Passing a
+// method-specific Factory allows this one call to Do to inject a Policy into the linked-list. The policy is injected where
+// the MethodFactoryMarker (see the pipeline.MethodFactoryMarker function) is in the slice of Factory objects.
+//
+// When Do is called, the Pipeline object asks each Factory object to construct its Policy object and adds each Policy to a linked-list.
+// THen, Do sends the Context and Request through all the Policy objects. The final Policy object sends the request over the network
+// (via the HTTPSender object passed to NewPipeline) and the response is returned backwards through all the Policy objects.
+// Since Pipeline and Factory objects are goroutine-safe, you typically create 1 Pipeline object and reuse it to make many HTTP requests.
+type Pipeline interface {
+ Do(ctx context.Context, methodFactory Factory, request Request) (Response, error)
+}
+
+// NewPipeline creates a new goroutine-safe Pipeline object from the slice of Factory objects and the specified options.
+func NewPipeline(factories []Factory, o Options) Pipeline {
+ if o.HTTPSender == nil {
+ o.HTTPSender = newDefaultHTTPClientFactory()
+ }
+ if o.Log.Log == nil {
+ o.Log.Log = func(LogLevel, string) {} // No-op logger
+ }
+ return &pipeline{factories: factories, options: o}
+}
+
+// Do is called for each and every HTTP request. It tells each Factory to create its own (mutable) Policy object
+// replacing a MethodFactoryMarker factory (if it exists) with the methodFactory passed in. Then, the Context and Request
+// are sent through the pipeline of Policy objects (which can transform the Request's URL/query parameters/headers) and
+// ultimately sends the transformed HTTP request over the network.
+func (p *pipeline) Do(ctx context.Context, methodFactory Factory, request Request) (Response, error) {
+ response, err := p.newPolicies(methodFactory).Do(ctx, request)
+ request.close()
+ return response, err
+}
+
+func (p *pipeline) newPolicies(methodFactory Factory) Policy {
+ // The last Policy is the one that actually sends the request over the wire and gets the response.
+ // It is overridable via the Options' HTTPSender field.
+ po := &PolicyOptions{pipeline: p} // One object shared by all policy objects
+ next := p.options.HTTPSender.New(nil, po)
+
+ // Walk over the slice of Factory objects in reverse (from wire to API)
+ markers := 0
+ for i := len(p.factories) - 1; i >= 0; i-- {
+ factory := p.factories[i]
+ if _, ok := factory.(methodFactoryMarker); ok {
+ markers++
+ if markers > 1 {
+ panic("MethodFactoryMarker can only appear once in the pipeline")
+ }
+ if methodFactory != nil {
+ // Replace MethodFactoryMarker with passed-in methodFactory
+ next = methodFactory.New(next, po)
+ }
+ } else {
+ // Use the slice's Factory to construct its Policy
+ next = factory.New(next, po)
+ }
+ }
+
+ // Each Factory has created its Policy
+ if markers == 0 && methodFactory != nil {
+ panic("Non-nil methodFactory requires MethodFactoryMarker in the pipeline")
+ }
+ return next // Return head of the Policy object linked-list
+}
+
+// A PolicyOptions represents optional information that can be used by a node in the
+// linked-list of Policy objects. A PolicyOptions is passed to the Factory's New method
+// which passes it (if desired) to the Policy object it creates. Today, the Policy object
+// uses the options to perform logging. But, in the future, this could be used for more.
+type PolicyOptions struct {
+ pipeline *pipeline
+}
+
+// ShouldLog returns true if the specified log level should be logged.
+func (po *PolicyOptions) ShouldLog(level LogLevel) bool {
+ if po.pipeline.options.Log.ShouldLog != nil {
+ return po.pipeline.options.Log.ShouldLog(level)
+ }
+ return false
+}
+
+// Log logs a string to the Pipeline's Logger.
+func (po *PolicyOptions) Log(level LogLevel, msg string) {
+ if !po.ShouldLog(level) {
+ return // Short circuit message formatting if we're not logging it
+ }
+
+ // We are logging it, ensure trailing newline
+ if len(msg) == 0 || msg[len(msg)-1] != '\n' {
+ msg += "\n" // Ensure trailing newline
+ }
+ po.pipeline.options.Log.Log(level, msg)
+
+ // If logger doesn't handle fatal/panic, we'll do it here.
+ if level == LogFatal {
+ os.Exit(1)
+ } else if level == LogPanic {
+ panic(msg)
+ }
+}
+
+var pipelineHTTPClient = newDefaultHTTPClient()
+
+func newDefaultHTTPClient() *http.Client {
+ // We want the Transport to have a large connection pool
+ return &http.Client{
+ Transport: &http.Transport{
+ Proxy: http.ProxyFromEnvironment,
+ // We use Dial instead of DialContext as DialContext has been reported to cause slower performance.
+ Dial /*Context*/ : (&net.Dialer{
+ Timeout: 30 * time.Second,
+ KeepAlive: 30 * time.Second,
+ DualStack: true,
+ }).Dial, /*Context*/
+ MaxIdleConns: 0, // No limit
+ MaxIdleConnsPerHost: 100,
+ IdleConnTimeout: 90 * time.Second,
+ TLSHandshakeTimeout: 10 * time.Second,
+ ExpectContinueTimeout: 1 * time.Second,
+ DisableKeepAlives: false,
+ DisableCompression: false,
+ MaxResponseHeaderBytes: 0,
+ //ResponseHeaderTimeout: time.Duration{},
+ //ExpectContinueTimeout: time.Duration{},
+ },
+ }
+}
+
+// newDefaultHTTPClientFactory creates a DefaultHTTPClientPolicyFactory object that sends HTTP requests to a Go's default http.Client.
+func newDefaultHTTPClientFactory() Factory {
+ return FactoryFunc(func(next Policy, po *PolicyOptions) PolicyFunc {
+ return func(ctx context.Context, request Request) (Response, error) {
+ r, err := pipelineHTTPClient.Do(request.WithContext(ctx))
+ if err != nil {
+ err = NewError(err, "HTTP request failed")
+ }
+ return NewHTTPResponse(r), err
+ }
+ })
+}
+
+var mfm = methodFactoryMarker{} // Singleton
+
+// MethodFactoryMarker returns a special marker Factory object. When Pipeline's Do method is called, any
+// MethodMarkerFactory object is replaced with the specified methodFactory object. If nil is passed fro Do's
+// methodFactory parameter, then the MethodFactoryMarker is ignored as the linked-list of Policy objects is created.
+func MethodFactoryMarker() Factory {
+ return mfm
+}
+
+type methodFactoryMarker struct {
+}
+
+func (methodFactoryMarker) New(next Policy, po *PolicyOptions) Policy {
+ panic("methodFactoryMarker policy should have been replaced with a method policy")
+}
diff --git a/vendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_syslog.go b/vendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_syslog.go
new file mode 100755
index 000000000..d0bb77407
--- /dev/null
+++ b/vendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_syslog.go
@@ -0,0 +1,33 @@
+// +build !windows,!nacl,!plan9
+
+package pipeline
+
+import (
+ "log"
+ "log/syslog"
+)
+
+// ForceLog should rarely be used. It forceable logs an entry to the
+// Windows Event Log (on Windows) or to the SysLog (on Linux)
+func ForceLog(level LogLevel, msg string) {
+ if defaultLogger == nil {
+ return // Return fast if we failed to create the logger.
+ }
+ // We are logging it, ensure trailing newline
+ if len(msg) == 0 || msg[len(msg)-1] != '\n' {
+ msg += "\n" // Ensure trailing newline
+ }
+ switch level {
+ case LogFatal:
+ defaultLogger.Fatal(msg)
+ case LogPanic:
+ defaultLogger.Panic(msg)
+ case LogError, LogWarning, LogInfo:
+ defaultLogger.Print(msg)
+ }
+}
+
+var defaultLogger = func() *log.Logger {
+ l, _ := syslog.NewLogger(syslog.LOG_USER|syslog.LOG_WARNING, log.LstdFlags)
+ return l
+}()
diff --git a/vendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_windows.go b/vendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_windows.go
new file mode 100755
index 000000000..cb6739899
--- /dev/null
+++ b/vendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_windows.go
@@ -0,0 +1,61 @@
+package pipeline
+
+import (
+ "os"
+ "syscall"
+ "unsafe"
+)
+
+// ForceLog should rarely be used. It forceable logs an entry to the
+// Windows Event Log (on Windows) or to the SysLog (on Linux)
+func ForceLog(level LogLevel, msg string) {
+ var el eventType
+ switch level {
+ case LogError, LogFatal, LogPanic:
+ el = elError
+ case LogWarning:
+ el = elWarning
+ case LogInfo:
+ el = elInfo
+ }
+ // We are logging it, ensure trailing newline
+ if len(msg) == 0 || msg[len(msg)-1] != '\n' {
+ msg += "\n" // Ensure trailing newline
+ }
+ reportEvent(el, 0, msg)
+}
+
+type eventType int16
+
+const (
+ elSuccess eventType = 0
+ elError eventType = 1
+ elWarning eventType = 2
+ elInfo eventType = 4
+)
+
+var reportEvent = func() func(eventType eventType, eventID int32, msg string) {
+ advAPI32 := syscall.MustLoadDLL("AdvAPI32.dll")
+ registerEventSource := advAPI32.MustFindProc("RegisterEventSourceW")
+
+ sourceName, _ := os.Executable()
+ sourceNameUTF16, _ := syscall.UTF16PtrFromString(sourceName)
+ handle, _, lastErr := registerEventSource.Call(uintptr(0), uintptr(unsafe.Pointer(sourceNameUTF16)))
+ if lastErr == nil { // On error, logging is a no-op
+ return func(eventType eventType, eventID int32, msg string) {}
+ }
+ reportEvent := advAPI32.MustFindProc("ReportEventW")
+ return func(eventType eventType, eventID int32, msg string) {
+ s, _ := syscall.UTF16PtrFromString(msg)
+ _, _, _ = reportEvent.Call(
+ uintptr(handle), // HANDLE hEventLog
+ uintptr(eventType), // WORD wType
+ uintptr(0), // WORD wCategory
+ uintptr(eventID), // DWORD dwEventID
+ uintptr(0), // PSID lpUserSid
+ uintptr(1), // WORD wNumStrings
+ uintptr(0), // DWORD dwDataSize
+ uintptr(unsafe.Pointer(&s)), // LPCTSTR *lpStrings
+ uintptr(0)) // LPVOID lpRawData
+ }
+}()
diff --git a/vendor/github.com/Azure/azure-pipeline-go/pipeline/doc.go b/vendor/github.com/Azure/azure-pipeline-go/pipeline/doc.go
new file mode 100755
index 000000000..b5ab05f4d
--- /dev/null
+++ b/vendor/github.com/Azure/azure-pipeline-go/pipeline/doc.go
@@ -0,0 +1,161 @@
+// Copyright 2017 Microsoft Corporation. All rights reserved.
+// Use of this source code is governed by an MIT
+// license that can be found in the LICENSE file.
+
+/*
+Package pipeline implements an HTTP request/response middleware pipeline whose
+policy objects mutate an HTTP request's URL, query parameters, and/or headers before
+the request is sent over the wire.
+
+Not all policy objects mutate an HTTP request; some policy objects simply impact the
+flow of requests/responses by performing operations such as logging, retry policies,
+timeouts, failure injection, and deserialization of response payloads.
+
+Implementing the Policy Interface
+
+To implement a policy, define a struct that implements the pipeline.Policy interface's Do method. Your Do
+method is called when an HTTP request wants to be sent over the network. Your Do method can perform any
+operation(s) it desires. For example, it can log the outgoing request, mutate the URL, headers, and/or query
+parameters, inject a failure, etc. Your Do method must then forward the HTTP request to next Policy object
+in a linked-list ensuring that the remaining Policy objects perform their work. Ultimately, the last Policy
+object sends the HTTP request over the network (by calling the HTTPSender's Do method).
+
+When an HTTP response comes back, each Policy object in the linked-list gets a chance to process the response
+(in reverse order). The Policy object can log the response, retry the operation if due to a transient failure
+or timeout, deserialize the response body, etc. Ultimately, the last Policy object returns the HTTP response
+to the code that initiated the original HTTP request.
+
+Here is a template for how to define a pipeline.Policy object:
+
+ type myPolicy struct {
+ node PolicyNode
+ // TODO: Add configuration/setting fields here (if desired)...
+ }
+
+ func (p *myPolicy) Do(ctx context.Context, request pipeline.Request) (pipeline.Response, error) {
+ // TODO: Mutate/process the HTTP request here...
+ response, err := p.node.Do(ctx, request) // Forward HTTP request to next Policy & get HTTP response
+ // TODO: Mutate/process the HTTP response here...
+ return response, err // Return response/error to previous Policy
+ }
+
+Implementing the Factory Interface
+
+Each Policy struct definition requires a factory struct definition that implements the pipeline.Factory interface's New
+method. The New method is called when application code wants to initiate a new HTTP request. Factory's New method is
+passed a pipeline.PolicyNode object which contains a reference to the owning pipeline.Pipeline object (discussed later) and
+a reference to the next Policy object in the linked list. The New method should create its corresponding Policy object
+passing it the PolicyNode and any other configuration/settings fields appropriate for the specific Policy object.
+
+Here is a template for how to define a pipeline.Policy object:
+
+ // NOTE: Once created & initialized, Factory objects should be goroutine-safe (ex: immutable);
+ // this allows reuse (efficient use of memory) and makes these objects usable by multiple goroutines concurrently.
+ type myPolicyFactory struct {
+ // TODO: Add any configuration/setting fields if desired...
+ }
+
+ func (f *myPolicyFactory) New(node pipeline.PolicyNode) Policy {
+ return &myPolicy{node: node} // TODO: Also initialize any configuration/setting fields here (if desired)...
+ }
+
+Using your Factory and Policy objects via a Pipeline
+
+To use the Factory and Policy objects, an application constructs a slice of Factory objects and passes
+this slice to the pipeline.NewPipeline function.
+
+ func NewPipeline(factories []pipeline.Factory, sender pipeline.HTTPSender) Pipeline
+
+This function also requires an object implementing the HTTPSender interface. For simple scenarios,
+passing nil for HTTPSender causes a standard Go http.Client object to be created and used to actually
+send the HTTP response over the network. For more advanced scenarios, you can pass your own HTTPSender
+object in. This allows sharing of http.Client objects or the use of custom-configured http.Client objects
+or other objects that can simulate the network requests for testing purposes.
+
+Now that you have a pipeline.Pipeline object, you can create a pipeline.Request object (which is a simple
+wrapper around Go's standard http.Request object) and pass it to Pipeline's Do method along with passing a
+context.Context for cancelling the HTTP request (if desired).
+
+ type Pipeline interface {
+ Do(ctx context.Context, methodFactory pipeline.Factory, request pipeline.Request) (pipeline.Response, error)
+ }
+
+Do iterates over the slice of Factory objects and tells each one to create its corresponding
+Policy object. After the linked-list of Policy objects have been created, Do calls the first
+Policy object passing it the Context & HTTP request parameters. These parameters now flow through
+all the Policy objects giving each object a chance to look at and/or mutate the HTTP request.
+The last Policy object sends the message over the network.
+
+When the network operation completes, the HTTP response and error return values pass
+back through the same Policy objects in reverse order. Most Policy objects ignore the
+response/error but some log the result, retry the operation (depending on the exact
+reason the operation failed), or deserialize the response's body. Your own Policy
+objects can do whatever they like when processing outgoing requests or incoming responses.
+
+Note that after an I/O request runs to completion, the Policy objects for that request
+are garbage collected. However, Pipeline object (like Factory objects) are goroutine-safe allowing
+them to be created once and reused over many I/O operations. This allows for efficient use of
+memory and also makes them safely usable by multiple goroutines concurrently.
+
+Inserting a Method-Specific Factory into the Linked-List of Policy Objects
+
+While Pipeline and Factory objects can be reused over many different operations, it is
+common to have special behavior for a specific operation/method. For example, a method
+may need to deserialize the response's body to an instance of a specific data type.
+To accommodate this, the Pipeline's Do method takes an additional method-specific
+Factory object. The Do method tells this Factory to create a Policy object and
+injects this method-specific Policy object into the linked-list of Policy objects.
+
+When creating a Pipeline object, the slice of Factory objects passed must have 1
+(and only 1) entry marking where the method-specific Factory should be injected.
+The Factory marker is obtained by calling the pipeline.MethodFactoryMarker() function:
+
+ func MethodFactoryMarker() pipeline.Factory
+
+Creating an HTTP Request Object
+
+The HTTP request object passed to Pipeline's Do method is not Go's http.Request struct.
+Instead, it is a pipeline.Request struct which is a simple wrapper around Go's standard
+http.Request. You create a pipeline.Request object by calling the pipeline.NewRequest function:
+
+ func NewRequest(method string, url url.URL, options pipeline.RequestOptions) (request pipeline.Request, err error)
+
+To this function, you must pass a pipeline.RequestOptions that looks like this:
+
+ type RequestOptions struct {
+ // The readable and seekable stream to be sent to the server as the request's body.
+ Body io.ReadSeeker
+
+ // The callback method (if not nil) to be invoked to report progress as the stream is uploaded in the HTTP request.
+ Progress ProgressReceiver
+ }
+
+The method and struct ensure that the request's body stream is a read/seekable stream.
+A seekable stream is required so that upon retry, the final Policy object can seek
+the stream back to the beginning before retrying the network request and re-uploading the
+body. In addition, you can associate a ProgressReceiver callback function which will be
+invoked periodically to report progress while bytes are being read from the body stream
+and sent over the network.
+
+Processing the HTTP Response
+
+When an HTTP response comes in from the network, a reference to Go's http.Response struct is
+embedded in a struct that implements the pipeline.Response interface:
+
+ type Response interface {
+ Response() *http.Response
+ }
+
+This interface is returned through all the Policy objects. Each Policy object can call the Response
+interface's Response method to examine (or mutate) the embedded http.Response object.
+
+A Policy object can internally define another struct (implementing the pipeline.Response interface)
+that embeds an http.Response and adds additional fields and return this structure to other Policy
+objects. This allows a Policy object to deserialize the body to some other struct and return the
+original http.Response and the additional struct back through the Policy chain. Other Policy objects
+can see the Response but cannot see the additional struct with the deserialized body. After all the
+Policy objects have returned, the pipeline.Response interface is returned by Pipeline's Do method.
+The caller of this method can perform a type assertion attempting to get back to the struct type
+really returned by the Policy object. If the type assertion is successful, the caller now has
+access to both the http.Response and the deserialized struct object.*/
+package pipeline
diff --git a/vendor/github.com/Azure/azure-pipeline-go/pipeline/error.go b/vendor/github.com/Azure/azure-pipeline-go/pipeline/error.go
new file mode 100755
index 000000000..fd008364d
--- /dev/null
+++ b/vendor/github.com/Azure/azure-pipeline-go/pipeline/error.go
@@ -0,0 +1,121 @@
+package pipeline
+
+import (
+ "fmt"
+ "runtime"
+)
+
+type causer interface {
+ Cause() error
+}
+
+// ErrorNode can be an embedded field in a private error object. This field
+// adds Program Counter support and a 'cause' (reference to a preceding error).
+// When initializing a error type with this embedded field, initialize the
+// ErrorNode field by calling ErrorNode{}.Initialize(cause).
+type ErrorNode struct {
+ pc uintptr // Represents a Program Counter that you can get symbols for.
+ cause error // Refers to the preceding error (or nil)
+}
+
+// Error returns a string with the PC's symbols or "" if the PC is invalid.
+// When defining a new error type, have its Error method call this one passing
+// it the string representation of the error.
+func (e *ErrorNode) Error(msg string) string {
+ s := ""
+ if fn := runtime.FuncForPC(e.pc); fn != nil {
+ file, line := fn.FileLine(e.pc)
+ s = fmt.Sprintf("-> %v, %v:%v\n", fn.Name(), file, line)
+ }
+ s += msg + "\n\n"
+ if e.cause != nil {
+ s += e.cause.Error() + "\n"
+ }
+ return s
+}
+
+// Cause returns the error that preceded this error.
+func (e *ErrorNode) Cause() error { return e.cause }
+
+// Temporary returns true if the error occurred due to a temporary condition.
+func (e ErrorNode) Temporary() bool {
+ type temporary interface {
+ Temporary() bool
+ }
+
+ for err := e.cause; err != nil; {
+ if t, ok := err.(temporary); ok {
+ return t.Temporary()
+ }
+
+ if cause, ok := err.(causer); ok {
+ err = cause.Cause()
+ } else {
+ err = nil
+ }
+ }
+ return false
+}
+
+// Timeout returns true if the error occurred due to time expiring.
+func (e ErrorNode) Timeout() bool {
+ type timeout interface {
+ Timeout() bool
+ }
+
+ for err := e.cause; err != nil; {
+ if t, ok := err.(timeout); ok {
+ return t.Timeout()
+ }
+
+ if cause, ok := err.(causer); ok {
+ err = cause.Cause()
+ } else {
+ err = nil
+ }
+ }
+ return false
+}
+
+// Initialize is used to initialize an embedded ErrorNode field.
+// It captures the caller's program counter and saves the cause (preceding error).
+// To initialize the field, use "ErrorNode{}.Initialize(cause, 3)". A callersToSkip
+// value of 3 is very common; but, depending on your code nesting, you may need
+// a different value.
+func (ErrorNode) Initialize(cause error, callersToSkip int) ErrorNode {
+ // Get the PC of Initialize method's caller.
+ pc := [1]uintptr{}
+ _ = runtime.Callers(callersToSkip, pc[:])
+ return ErrorNode{pc: pc[0], cause: cause}
+}
+
+// Cause walks all the preceding errors and return the originating error.
+func Cause(err error) error {
+ for err != nil {
+ cause, ok := err.(causer)
+ if !ok {
+ break
+ }
+ err = cause.Cause()
+ }
+ return err
+}
+
+// NewError creates a simple string error (like Error.New). But, this
+// error also captures the caller's Program Counter and the preceding error.
+func NewError(cause error, msg string) error {
+ return &pcError{
+ ErrorNode: ErrorNode{}.Initialize(cause, 3),
+ msg: msg,
+ }
+}
+
+// pcError is a simple string error (like error.New) with an ErrorNode (PC & cause).
+type pcError struct {
+ ErrorNode
+ msg string
+}
+
+// Error satisfies the error interface. It shows the error with Program Counter
+// symbols and calls Error on the preceding error so you can see the full error chain.
+func (e *pcError) Error() string { return e.ErrorNode.Error(e.msg) }
diff --git a/vendor/github.com/Azure/azure-pipeline-go/pipeline/progress.go b/vendor/github.com/Azure/azure-pipeline-go/pipeline/progress.go
new file mode 100755
index 000000000..efa3c8ed0
--- /dev/null
+++ b/vendor/github.com/Azure/azure-pipeline-go/pipeline/progress.go
@@ -0,0 +1,82 @@
+package pipeline
+
+import "io"
+
+// ********** The following is common between the request body AND the response body.
+
+// ProgressReceiver defines the signature of a callback function invoked as progress is reported.
+type ProgressReceiver func(bytesTransferred int64)
+
+// ********** The following are specific to the request body (a ReadSeekCloser)
+
+// This struct is used when sending a body to the network
+type requestBodyProgress struct {
+ requestBody io.ReadSeeker // Seeking is required to support retries
+ pr ProgressReceiver
+}
+
+// NewRequestBodyProgress adds progress reporting to an HTTP request's body stream.
+func NewRequestBodyProgress(requestBody io.ReadSeeker, pr ProgressReceiver) io.ReadSeeker {
+ if pr == nil {
+ panic("pr must not be nil")
+ }
+ return &requestBodyProgress{requestBody: requestBody, pr: pr}
+}
+
+// Read reads a block of data from an inner stream and reports progress
+func (rbp *requestBodyProgress) Read(p []byte) (n int, err error) {
+ n, err = rbp.requestBody.Read(p)
+ if err != nil {
+ return
+ }
+ // Invokes the user's callback method to report progress
+ position, err := rbp.requestBody.Seek(0, io.SeekCurrent)
+ if err != nil {
+ panic(err)
+ }
+ rbp.pr(position)
+ return
+}
+
+func (rbp *requestBodyProgress) Seek(offset int64, whence int) (offsetFromStart int64, err error) {
+ return rbp.requestBody.Seek(offset, whence)
+}
+
+// requestBodyProgress supports Close but the underlying stream may not; if it does, Close will close it.
+func (rbp *requestBodyProgress) Close() error {
+ if c, ok := rbp.requestBody.(io.Closer); ok {
+ return c.Close()
+ }
+ return nil
+}
+
+// ********** The following are specific to the response body (a ReadCloser)
+
+// This struct is used when sending a body to the network
+type responseBodyProgress struct {
+ responseBody io.ReadCloser
+ pr ProgressReceiver
+ offset int64
+}
+
+// NewResponseBodyProgress adds progress reporting to an HTTP response's body stream.
+func NewResponseBodyProgress(responseBody io.ReadCloser, pr ProgressReceiver) io.ReadCloser {
+ if pr == nil {
+ panic("pr must not be nil")
+ }
+ return &responseBodyProgress{responseBody: responseBody, pr: pr, offset: 0}
+}
+
+// Read reads a block of data from an inner stream and reports progress
+func (rbp *responseBodyProgress) Read(p []byte) (n int, err error) {
+ n, err = rbp.responseBody.Read(p)
+ rbp.offset += int64(n)
+
+ // Invokes the user's callback method to report progress
+ rbp.pr(rbp.offset)
+ return
+}
+
+func (rbp *responseBodyProgress) Close() error {
+ return rbp.responseBody.Close()
+}
diff --git a/vendor/github.com/Azure/azure-pipeline-go/pipeline/request.go b/vendor/github.com/Azure/azure-pipeline-go/pipeline/request.go
new file mode 100755
index 000000000..1fbe72bd4
--- /dev/null
+++ b/vendor/github.com/Azure/azure-pipeline-go/pipeline/request.go
@@ -0,0 +1,147 @@
+package pipeline
+
+import (
+ "io"
+ "net/http"
+ "net/url"
+ "strconv"
+)
+
+// Request is a thin wrapper over an http.Request. The wrapper provides several helper methods.
+type Request struct {
+ *http.Request
+}
+
+// NewRequest initializes a new HTTP request object with any desired options.
+func NewRequest(method string, url url.URL, body io.ReadSeeker) (request Request, err error) {
+ // Note: the url is passed by value so that any pipeline operations that modify it do so on a copy.
+
+ // This code to construct an http.Request is copied from http.NewRequest(); we intentionally omitted removeEmptyPort for now.
+ request.Request = &http.Request{
+ Method: method,
+ URL: &url,
+ Proto: "HTTP/1.1",
+ ProtoMajor: 1,
+ ProtoMinor: 1,
+ Header: make(http.Header),
+ Host: url.Host,
+ }
+
+ if body != nil {
+ err = request.SetBody(body)
+ }
+ return
+}
+
+// SetBody sets the body and content length, assumes body is not nil.
+func (r Request) SetBody(body io.ReadSeeker) error {
+ size, err := body.Seek(0, io.SeekEnd)
+ if err != nil {
+ return err
+ }
+
+ body.Seek(0, io.SeekStart)
+ r.ContentLength = size
+ r.Header["Content-Length"] = []string{strconv.FormatInt(size, 10)}
+
+ if size != 0 {
+ r.Body = &retryableRequestBody{body: body}
+ r.GetBody = func() (io.ReadCloser, error) {
+ _, err := body.Seek(0, io.SeekStart)
+ if err != nil {
+ return nil, err
+ }
+ return r.Body, nil
+ }
+ } else {
+ // in case the body is an empty stream, we need to use http.NoBody to explicitly provide no content
+ r.Body = http.NoBody
+ r.GetBody = func() (io.ReadCloser, error) {
+ return http.NoBody, nil
+ }
+
+ // close the user-provided empty body
+ if c, ok := body.(io.Closer); ok {
+ c.Close()
+ }
+ }
+
+ return nil
+}
+
+// Copy makes a copy of an http.Request. Specifically, it makes a deep copy
+// of its Method, URL, Host, Proto(Major/Minor), Header. ContentLength, Close,
+// RemoteAddr, RequestURI. Copy makes a shallow copy of the Body, GetBody, TLS,
+// Cancel, Response, and ctx fields. Copy panics if any of these fields are
+// not nil: TransferEncoding, Form, PostForm, MultipartForm, or Trailer.
+func (r Request) Copy() Request {
+ if r.TransferEncoding != nil || r.Form != nil || r.PostForm != nil || r.MultipartForm != nil || r.Trailer != nil {
+ panic("Can't make a deep copy of the http.Request because at least one of the following is not nil:" +
+ "TransferEncoding, Form, PostForm, MultipartForm, or Trailer.")
+ }
+ copy := *r.Request // Copy the request
+ urlCopy := *(r.Request.URL) // Copy the URL
+ copy.URL = &urlCopy
+ copy.Header = http.Header{} // Copy the header
+ for k, vs := range r.Header {
+ for _, value := range vs {
+ copy.Header.Add(k, value)
+ }
+ }
+ return Request{Request: &copy} // Return the copy
+}
+
+func (r Request) close() error {
+ if r.Body != nil && r.Body != http.NoBody {
+ c, ok := r.Body.(*retryableRequestBody)
+ if !ok {
+ panic("unexpected request body type (should be *retryableReadSeekerCloser)")
+ }
+ return c.realClose()
+ }
+ return nil
+}
+
+// RewindBody seeks the request's Body stream back to the beginning so it can be resent when retrying an operation.
+func (r Request) RewindBody() error {
+ if r.Body != nil && r.Body != http.NoBody {
+ s, ok := r.Body.(io.Seeker)
+ if !ok {
+ panic("unexpected request body type (should be io.Seeker)")
+ }
+
+ // Reset the stream back to the beginning
+ _, err := s.Seek(0, io.SeekStart)
+ return err
+ }
+ return nil
+}
+
+// ********** The following type/methods implement the retryableRequestBody (a ReadSeekCloser)
+
+// This struct is used when sending a body to the network
+type retryableRequestBody struct {
+ body io.ReadSeeker // Seeking is required to support retries
+}
+
+// Read reads a block of data from an inner stream and reports progress
+func (b *retryableRequestBody) Read(p []byte) (n int, err error) {
+ return b.body.Read(p)
+}
+
+func (b *retryableRequestBody) Seek(offset int64, whence int) (offsetFromStart int64, err error) {
+ return b.body.Seek(offset, whence)
+}
+
+func (b *retryableRequestBody) Close() error {
+ // We don't want the underlying transport to close the request body on transient failures so this is a nop.
+ // The pipeline closes the request body upon success.
+ return nil
+}
+
+func (b *retryableRequestBody) realClose() error {
+ if c, ok := b.body.(io.Closer); ok {
+ return c.Close()
+ }
+ return nil
+}
diff --git a/vendor/github.com/Azure/azure-pipeline-go/pipeline/response.go b/vendor/github.com/Azure/azure-pipeline-go/pipeline/response.go
new file mode 100755
index 000000000..f2dc16482
--- /dev/null
+++ b/vendor/github.com/Azure/azure-pipeline-go/pipeline/response.go
@@ -0,0 +1,74 @@
+package pipeline
+
+import (
+ "bytes"
+ "fmt"
+ "net/http"
+ "sort"
+ "strings"
+)
+
+// The Response interface exposes an http.Response object as it returns through the pipeline of Policy objects.
+// This ensures that Policy objects have access to the HTTP response. However, the object this interface encapsulates
+// might be a struct with additional fields that is created by a Policy object (typically a method-specific Factory).
+// The method that injected the method-specific Factory gets this returned Response and performs a type assertion
+// to the expected struct and returns the struct to its caller.
+type Response interface {
+ Response() *http.Response
+}
+
+// This is the default struct that has the http.Response.
+// A method can replace this struct with its own struct containing an http.Response
+// field and any other additional fields.
+type httpResponse struct {
+ response *http.Response
+}
+
+// NewHTTPResponse is typically called by a Policy object to return a Response object.
+func NewHTTPResponse(response *http.Response) Response {
+ return &httpResponse{response: response}
+}
+
+// This method satisfies the public Response interface's Response method
+func (r httpResponse) Response() *http.Response {
+ return r.response
+}
+
+// WriteRequestWithResponse appends a formatted HTTP request into a Buffer. If request and/or err are
+// not nil, then these are also written into the Buffer.
+func WriteRequestWithResponse(b *bytes.Buffer, request *http.Request, response *http.Response, err error) {
+ // Write the request into the buffer.
+ fmt.Fprint(b, " "+request.Method+" "+request.URL.String()+"\n")
+ writeHeader(b, request.Header)
+ if response != nil {
+ fmt.Fprintln(b, " --------------------------------------------------------------------------------")
+ fmt.Fprint(b, " RESPONSE Status: "+response.Status+"\n")
+ writeHeader(b, response.Header)
+ }
+ if err != nil {
+ fmt.Fprintln(b, " --------------------------------------------------------------------------------")
+ fmt.Fprint(b, " ERROR:\n"+err.Error()+"\n")
+ }
+}
+
+// formatHeaders appends an HTTP request's or response's header into a Buffer.
+func writeHeader(b *bytes.Buffer, header map[string][]string) {
+ if len(header) == 0 {
+ b.WriteString(" (no headers)\n")
+ return
+ }
+ keys := make([]string, 0, len(header))
+ // Alphabetize the headers
+ for k := range header {
+ keys = append(keys, k)
+ }
+ sort.Strings(keys)
+ for _, k := range keys {
+ // Redact the value of any Authorization header to prevent security information from persisting in logs
+ value := interface{}("REDACTED")
+ if !strings.EqualFold(k, "Authorization") {
+ value = header[k]
+ }
+ fmt.Fprintf(b, " %s: %+v\n", k, value)
+ }
+}
diff --git a/vendor/github.com/Azure/azure-pipeline-go/pipeline/version.go b/vendor/github.com/Azure/azure-pipeline-go/pipeline/version.go
new file mode 100644
index 000000000..c4bb62d81
--- /dev/null
+++ b/vendor/github.com/Azure/azure-pipeline-go/pipeline/version.go
@@ -0,0 +1,9 @@
+package pipeline
+
+const (
+ // UserAgent is the string to be used in the user agent string when making requests.
+ UserAgent = "azure-pipeline-go/" + Version
+
+ // Version is the semantic version (see http://semver.org) of the pipeline package.
+ Version = "0.1.0"
+)