aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/aws/aws-sdk-go/aws/request/request.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/aws/aws-sdk-go/aws/request/request.go')
-rw-r--r--vendor/github.com/aws/aws-sdk-go/aws/request/request.go657
1 files changed, 0 insertions, 657 deletions
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request.go
deleted file mode 100644
index 75f0fe0..0000000
--- a/vendor/github.com/aws/aws-sdk-go/aws/request/request.go
+++ /dev/null
@@ -1,657 +0,0 @@
-package request
-
-import (
- "bytes"
- "fmt"
- "io"
- "net"
- "net/http"
- "net/url"
- "reflect"
- "strings"
- "time"
-
- "github.com/aws/aws-sdk-go/aws"
- "github.com/aws/aws-sdk-go/aws/awserr"
- "github.com/aws/aws-sdk-go/aws/client/metadata"
- "github.com/aws/aws-sdk-go/internal/sdkio"
-)
-
-const (
- // ErrCodeSerialization is the serialization error code that is received
- // during protocol unmarshaling.
- ErrCodeSerialization = "SerializationError"
-
- // ErrCodeRead is an error that is returned during HTTP reads.
- ErrCodeRead = "ReadError"
-
- // ErrCodeResponseTimeout is the connection timeout error that is received
- // 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.
- CanceledErrorCode = "RequestCanceled"
-)
-
-// A Request is the service request to be made.
-type Request struct {
- Config aws.Config
- ClientInfo metadata.ClientInfo
- Handlers Handlers
-
- Retryer
- AttemptTime time.Time
- Time time.Time
- Operation *Operation
- HTTPRequest *http.Request
- HTTPResponse *http.Response
- Body io.ReadSeeker
- BodyStart int64 // offset from beginning of Body that the request body starts
- Params interface{}
- Error error
- Data interface{}
- RequestID string
- RetryCount int
- Retryable *bool
- RetryDelay time.Duration
- NotHoist bool
- SignedHeaderVals http.Header
- 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
-
- // Need to persist an intermediate body between the input Body and HTTP
- // request body because the HTTP Client's transport can maintain a reference
- // to the HTTP request's body after the client has returned. This value is
- // safe to use concurrently and wrap the input Body for each HTTP request.
- safeBody *offsetReader
-}
-
-// An Operation is the service API operation to be made.
-type Operation struct {
- Name string
- HTTPMethod string
- HTTPPath string
- *Paginator
-
- BeforePresignFn func(r *Request) error
-}
-
-// New returns a new Request pointer for the service API
-// operation and parameters.
-//
-// Params is any value of input parameters to be the request payload.
-// Data is pointer value to an object which the request's response
-// payload will be deserialized to.
-func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers,
- retryer Retryer, operation *Operation, params interface{}, data interface{}) *Request {
-
- method := operation.HTTPMethod
- if method == "" {
- method = "POST"
- }
-
- httpReq, _ := http.NewRequest(method, "", nil)
-
- var err error
- httpReq.URL, err = url.Parse(clientInfo.Endpoint + operation.HTTPPath)
- if err != nil {
- httpReq.URL = &url.URL{}
- err = awserr.New("InvalidEndpointURL", "invalid endpoint uri", err)
- }
-
- SanitizeHostForHeader(httpReq)
-
- r := &Request{
- Config: cfg,
- ClientInfo: clientInfo,
- Handlers: handlers.Copy(),
-
- Retryer: retryer,
- AttemptTime: time.Now(),
- Time: time.Now(),
- ExpireTime: 0,
- Operation: operation,
- HTTPRequest: httpReq,
- Body: nil,
- Params: params,
- Error: err,
- Data: data,
- }
- r.SetBufferBody([]byte{})
-
- return r
-}
-
-// A Option is a functional option that can augment or modify a request when
-// using a WithContext API operation method.
-type Option func(*Request)
-
-// WithGetResponseHeader builds a request Option which will retrieve a single
-// header value from the HTTP Response. If there are multiple values for the
-// header key use WithGetResponseHeaders instead to access the http.Header
-// map directly. The passed in val pointer must be non-nil.
-//
-// This Option can be used multiple times with a single API operation.
-//
-// var id2, versionID string
-// svc.PutObjectWithContext(ctx, params,
-// request.WithGetResponseHeader("x-amz-id-2", &id2),
-// request.WithGetResponseHeader("x-amz-version-id", &versionID),
-// )
-func WithGetResponseHeader(key string, val *string) Option {
- return func(r *Request) {
- r.Handlers.Complete.PushBack(func(req *Request) {
- *val = req.HTTPResponse.Header.Get(key)
- })
- }
-}
-
-// WithGetResponseHeaders builds a request Option which will retrieve the
-// headers from the HTTP response and assign them to the passed in headers
-// variable. The passed in headers pointer must be non-nil.
-//
-// var headers http.Header
-// svc.PutObjectWithContext(ctx, params, request.WithGetResponseHeaders(&headers))
-func WithGetResponseHeaders(headers *http.Header) Option {
- return func(r *Request) {
- r.Handlers.Complete.PushBack(func(req *Request) {
- *headers = req.HTTPResponse.Header
- })
- }
-}
-
-// WithLogLevel is a request option that will set the request to use a specific
-// log level when the request is made.
-//
-// svc.PutObjectWithContext(ctx, params, request.WithLogLevel(aws.LogDebugWithHTTPBody)
-func WithLogLevel(l aws.LogLevelType) Option {
- return func(r *Request) {
- r.Config.LogLevel = aws.LogLevel(l)
- }
-}
-
-// ApplyOptions will apply each option to the request calling them in the order
-// the were provided.
-func (r *Request) ApplyOptions(opts ...Option) {
- for _, opt := range opts {
- opt(r)
- }
-}
-
-// Context will always returns a non-nil context. If Request does not have a
-// context aws.BackgroundContext will be returned.
-func (r *Request) Context() aws.Context {
- if r.context != nil {
- return r.context
- }
- return aws.BackgroundContext()
-}
-
-// SetContext adds a Context to the current request that can be used to cancel
-// a in-flight request. The Context value must not be nil, or this method will
-// panic.
-//
-// Unlike http.Request.WithContext, SetContext does not return a copy of the
-// Request. It is not safe to use use a single Request value for multiple
-// requests. A new Request should be created for each API operation request.
-//
-// Go 1.6 and below:
-// The http.Request's Cancel field will be set to the Done() value of
-// the context. This will overwrite the Cancel field's value.
-//
-// Go 1.7 and above:
-// The http.Request.WithContext will be used to set the context on the underlying
-// http.Request. This will create a shallow copy of the http.Request. The SDK
-// may create sub contexts in the future for nested requests such as retries.
-func (r *Request) SetContext(ctx aws.Context) {
- if ctx == nil {
- panic("context cannot be nil")
- }
- setRequestContext(r, ctx)
-}
-
-// WillRetry returns if the request's can be retried.
-func (r *Request) WillRetry() bool {
- if !aws.IsReaderSeekable(r.Body) && r.HTTPRequest.Body != NoBody {
- return false
- }
- return r.Error != nil && aws.BoolValue(r.Retryable) && r.RetryCount < r.MaxRetries()
-}
-
-// ParamsFilled returns if the request's parameters have been populated
-// and the parameters are valid. False is returned if no parameters are
-// provided or invalid.
-func (r *Request) ParamsFilled() bool {
- return r.Params != nil && reflect.ValueOf(r.Params).Elem().IsValid()
-}
-
-// DataFilled returns true if the request's data for response deserialization
-// target has been set and is a valid. False is returned if data is not
-// set, or is invalid.
-func (r *Request) DataFilled() bool {
- return r.Data != nil && reflect.ValueOf(r.Data).Elem().IsValid()
-}
-
-// SetBufferBody will set the request's body bytes that will be sent to
-// the service API.
-func (r *Request) SetBufferBody(buf []byte) {
- r.SetReaderBody(bytes.NewReader(buf))
-}
-
-// SetStringBody sets the body of the request to be backed by a string.
-func (r *Request) SetStringBody(s string) {
- r.SetReaderBody(strings.NewReader(s))
-}
-
-// SetReaderBody will set the request's body reader.
-func (r *Request) SetReaderBody(reader io.ReadSeeker) {
- r.Body = reader
- r.BodyStart, _ = reader.Seek(0, sdkio.SeekCurrent) // Get the Bodies current offset.
- r.ResetBody()
-}
-
-// Presign returns the request's signed URL. Error will be returned
-// if the signing fails.
-//
-// 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
-
- 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(expire time.Duration) (string, http.Header, error) {
- r = r.copy()
- return getPresignedURL(r, expire)
-}
-
-// IsPresigned returns true if the request represents a presigned API url.
-func (r *Request) IsPresigned() bool {
- return r.ExpireTime != 0
-}
-
-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
-}
-
-func debugLogReqError(r *Request, stage string, retrying bool, err error) {
- if !r.Config.LogLevel.Matches(aws.LogDebugWithRequestErrors) {
- return
- }
-
- retryStr := "not retrying"
- if retrying {
- retryStr = "will retry"
- }
-
- r.Config.Logger.Log(fmt.Sprintf("DEBUG: %s %s/%s failed, %s, error %v",
- stage, r.ClientInfo.ServiceName, r.Operation.Name, retryStr, err))
-}
-
-// Build will build the request's object so it can be signed and sent
-// to the service. Build will also validate all the request's parameters.
-// Any additional build Handlers set on this request will be run
-// in the order they were set.
-//
-// The request will only be built once. Multiple calls to build will have
-// no effect.
-//
-// If any Validate or Build errors occur the build will stop and the error
-// which occurred will be returned.
-func (r *Request) Build() error {
- if !r.built {
- r.Handlers.Validate.Run(r)
- if r.Error != nil {
- debugLogReqError(r, "Validate Request", false, r.Error)
- return r.Error
- }
- r.Handlers.Build.Run(r)
- if r.Error != nil {
- debugLogReqError(r, "Build Request", false, r.Error)
- return r.Error
- }
- r.built = true
- }
-
- return r.Error
-}
-
-// Sign will sign the request, returning error if errors are encountered.
-//
-// Sign will build the request prior to signing. All Sign Handlers will
-// be executed in the order they were set.
-func (r *Request) Sign() error {
- r.Build()
- if r.Error != nil {
- debugLogReqError(r, "Build Request", false, r.Error)
- return r.Error
- }
-
- r.Handlers.Sign.Run(r)
- return r.Error
-}
-
-func (r *Request) getNextRequestBody() (io.ReadCloser, error) {
- if r.safeBody != nil {
- r.safeBody.Close()
- }
-
- r.safeBody = newOffsetReader(r.Body, r.BodyStart)
-
- // Go 1.8 tightened and clarified the rules code needs to use when building
- // requests with the http package. Go 1.8 removed the automatic detection
- // of if the Request.Body was empty, or actually had bytes in it. The SDK
- // always sets the Request.Body even if it is empty and should not actually
- // be sent. This is incorrect.
- //
- // Go 1.8 did add a http.NoBody value that the SDK can use to tell the http
- // client that the request really should be sent without a body. The
- // Request.Body cannot be set to nil, which is preferable, because the
- // field is exported and could introduce nil pointer dereferences for users
- // of the SDK if they used that field.
- //
- // Related golang/go#18257
- l, err := aws.SeekerLen(r.Body)
- if err != nil {
- return nil, awserr.New(ErrCodeSerialization, "failed to compute request body size", err)
- }
-
- var body io.ReadCloser
- if l == 0 {
- body = NoBody
- } else if l > 0 {
- body = r.safeBody
- } else {
- // Hack to prevent sending bodies for methods where the body
- // should be ignored by the server. Sending bodies on these
- // methods without an associated ContentLength will cause the
- // request to socket timeout because the server does not handle
- // Transfer-Encoding: chunked bodies for these methods.
- //
- // This would only happen if a aws.ReaderSeekerCloser was used with
- // a io.Reader that was not also an io.Seeker, or did not implement
- // Len() method.
- switch r.Operation.HTTPMethod {
- case "GET", "HEAD", "DELETE":
- body = NoBody
- default:
- body = r.safeBody
- }
- }
-
- return body, nil
-}
-
-// GetBody will return an io.ReadSeeker of the Request's underlying
-// input body with a concurrency safe wrapper.
-func (r *Request) GetBody() io.ReadSeeker {
- return r.safeBody
-}
-
-// Send will send the request, returning error if errors are encountered.
-//
-// Send will sign the request prior to sending. All Send Handlers will
-// be executed in the order they were set.
-//
-// Canceling a request is non-deterministic. If a request has been canceled,
-// then the transport will choose, randomly, one of the state channels during
-// reads or getting the connection.
-//
-// readLoop() and getConn(req *Request, cm connectMethod)
-// https://github.com/golang/go/blob/master/src/net/http/transport.go
-//
-// Send will not close the request.Request's body.
-func (r *Request) Send() error {
- defer func() {
- // Regardless of success or failure of the request trigger the Complete
- // request handlers.
- r.Handlers.Complete.Run(r)
- }()
-
- for {
- r.AttemptTime = time.Now()
- if aws.BoolValue(r.Retryable) {
- if r.Config.LogLevel.Matches(aws.LogDebugWithRequestRetries) {
- r.Config.Logger.Log(fmt.Sprintf("DEBUG: Retrying Request %s/%s, attempt %d",
- r.ClientInfo.ServiceName, r.Operation.Name, r.RetryCount))
- }
-
- // The previous http.Request will have a reference to the r.Body
- // and the HTTP Client's Transport may still be reading from
- // the request's body even though the Client's Do returned.
- r.HTTPRequest = copyHTTPRequest(r.HTTPRequest, nil)
- r.ResetBody()
-
- // Closing response body to ensure that no response body is leaked
- // between retry attempts.
- if r.HTTPResponse != nil && r.HTTPResponse.Body != nil {
- r.HTTPResponse.Body.Close()
- }
- }
-
- r.Sign()
- if r.Error != nil {
- return r.Error
- }
-
- r.Retryable = nil
-
- r.Handlers.Send.Run(r)
- if r.Error != nil {
- if !shouldRetryCancel(r) {
- return r.Error
- }
-
- err := r.Error
- r.Handlers.Retry.Run(r)
- r.Handlers.AfterRetry.Run(r)
- if r.Error != nil {
- debugLogReqError(r, "Send Request", false, err)
- return r.Error
- }
- debugLogReqError(r, "Send Request", true, err)
- continue
- }
- r.Handlers.UnmarshalMeta.Run(r)
- r.Handlers.ValidateResponse.Run(r)
- if r.Error != nil {
- r.Handlers.UnmarshalError.Run(r)
- err := r.Error
-
- r.Handlers.Retry.Run(r)
- r.Handlers.AfterRetry.Run(r)
- if r.Error != nil {
- debugLogReqError(r, "Validate Response", false, err)
- return r.Error
- }
- debugLogReqError(r, "Validate Response", true, err)
- continue
- }
-
- r.Handlers.Unmarshal.Run(r)
- if r.Error != nil {
- err := r.Error
- r.Handlers.Retry.Run(r)
- r.Handlers.AfterRetry.Run(r)
- if r.Error != nil {
- debugLogReqError(r, "Unmarshal Response", false, err)
- return r.Error
- }
- debugLogReqError(r, "Unmarshal Response", true, err)
- continue
- }
-
- break
- }
-
- return nil
-}
-
-// copy will copy a request which will allow for local manipulation of the
-// request.
-func (r *Request) copy() *Request {
- req := &Request{}
- *req = *r
- req.Handlers = r.Handlers.Copy()
- op := *r.Operation
- req.Operation = &op
- return req
-}
-
-// AddToUserAgent adds the string to the end of the request's current user agent.
-func AddToUserAgent(r *Request, s string) {
- curUA := r.HTTPRequest.Header.Get("User-Agent")
- if len(curUA) > 0 {
- s = curUA + " " + s
- }
- r.HTTPRequest.Header.Set("User-Agent", s)
-}
-
-func shouldRetryCancel(r *Request) bool {
- awsErr, ok := r.Error.(awserr.Error)
- timeoutErr := false
- errStr := r.Error.Error()
- if ok {
- if awsErr.Code() == CanceledErrorCode {
- return false
- }
- err := awsErr.OrigErr()
- netErr, netOK := err.(net.Error)
- timeoutErr = netOK && netErr.Temporary()
- if urlErr, ok := err.(*url.Error); !timeoutErr && ok {
- errStr = urlErr.Err.Error()
- }
- }
-
- // There can be two types of canceled errors here.
- // The first being a net.Error and the other being an error.
- // If the request was timed out, we want to continue the retry
- // process. Otherwise, return the canceled error.
- return timeoutErr ||
- (errStr != "net/http: request canceled" &&
- 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
-}