func initHandlers(s *Session) { // Add the Validate parameter handler if it is not disabled. s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler) if !aws.BoolValue(s.Config.DisableParamValidation) { s.Handlers.Validate.PushBackNamed(corehandlers.ValidateParametersHandler) } }
// ClientConfig satisfies the client.ConfigProvider interface and is used to // configure the service client instances. Passing the Session to the service // client's constructor (New) will use this method to configure the client. // // Example: // sess := session.New() // s3.New(sess) func (s *Session) ClientConfig(serviceName string, cfgs ...*aws.Config) client.Config { s = s.Copy(cfgs...) endpoint, signingRegion := endpoints.NormalizeEndpoint( aws.StringValue(s.Config.Endpoint), serviceName, aws.StringValue(s.Config.Region), aws.BoolValue(s.Config.DisableSSL)) return client.Config{ Config: s.Config, Handlers: s.Handlers, Endpoint: endpoint, SigningRegion: signingRegion, } }
// CredChain returns the default credential chain. // // Generally you shouldn't need to use this method directly, but // is available if you need to reset the credentials of an // existing service client or session's Config. func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credentials { endpoint, signingRegion := endpoints.EndpointForRegion(ec2metadata.ServiceName, *cfg.Region, true) return credentials.NewCredentials(&credentials.ChainProvider{ VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors), Providers: []credentials.Provider{ &credentials.EnvProvider{}, &credentials.SharedCredentialsProvider{Filename: "", Profile: ""}, &ec2rolecreds.EC2RoleProvider{ Client: ec2metadata.NewClient(*cfg, handlers, endpoint, signingRegion), ExpiryWindow: 5 * time.Minute, }, }}) }
// nextPageTokens returns the tokens to use when asking for the next page of // data. func (r *Request) nextPageTokens() []interface{} { if r.Operation.Paginator == nil { return nil } if r.Operation.TruncationToken != "" { tr, _ := awsutil.ValuesAtPath(r.Data, r.Operation.TruncationToken) if len(tr) == 0 { return nil } switch v := tr[0].(type) { case *bool: if !aws.BoolValue(v) { return nil } case bool: if v == false { return nil } } } 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 { tokens = append(tokens, nil) } } if !tokenAdded { return nil } return tokens }
// NewClient returns a new EC2Metadata client. Should be used to create // a client when not using a session. Generally using just New with a session // is preferred. // // If an unmodified HTTP client is provided from the stdlib default, or no client // the EC2RoleProvider's EC2Metadata HTTP client's timeout will be shortened. // To disable this set Config.EC2MetadataDisableTimeoutOverride to false. Enabled by default. func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string, opts ...func(*client.Client)) *EC2Metadata { if !aws.BoolValue(cfg.EC2MetadataDisableTimeoutOverride) && httpClientZero(cfg.HTTPClient) { // If the http client is unmodified and this feature is not disabled // set custom timeouts for EC2Metadata requests. cfg.HTTPClient = &http.Client{ // use a shorter timeout than default because the metadata // service is local if it is running, and to fail faster // if not running on an ec2 instance. Timeout: 5 * time.Second, } } svc := &EC2Metadata{ Client: client.New( cfg, metadata.ClientInfo{ ServiceName: ServiceName, Endpoint: endpoint, APIVersion: "latest", }, handlers, ), } svc.Handlers.Unmarshal.PushBack(unmarshalHandler) svc.Handlers.UnmarshalError.PushBack(unmarshalError) svc.Handlers.Validate.Clear() svc.Handlers.Validate.PushBack(validateEndpointHandler) // Add additional options to the service config for _, option := range opts { option(svc.Client) } return svc }
// 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. func (r *Request) Send() error { for { r.Sign() if r.Error != nil { return r.Error } 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)) } // Re-seek the body back to the original point in for a retry so that // send will send the body's contents again in the upcoming request. r.Body.Seek(r.BodyStart, 0) r.HTTPRequest.Body = ioutil.NopCloser(r.Body) } r.Retryable = nil r.Handlers.Send.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, "Send Request", false, r.Error) return r.Error } debugLogReqError(r, "Send Request", true, err) continue } r.Handlers.UnmarshalMeta.Run(r) r.Handlers.ValidateResponse.Run(r) if r.Error != nil { err := r.Error r.Handlers.UnmarshalError.Run(r) r.Handlers.Retry.Run(r) r.Handlers.AfterRetry.Run(r) if r.Error != nil { debugLogReqError(r, "Validate Response", false, r.Error) 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, r.Error) return r.Error } debugLogReqError(r, "Unmarshal Response", true, err) continue } break } return nil }
// WillRetry returns if the request's can be retried. func (r *Request) WillRetry() bool { return r.Error != nil && aws.BoolValue(r.Retryable) && r.RetryCount < r.MaxRetries() }