func (t *tokenProvider) fetchTokenHandler(r *request.Request) {
	if v := atomic.LoadUint32(&t.disabled); v == 1 {
		return
	}
	if ec2Token, ok := t.token.Load().(ec2Token); ok && !ec2Token.IsExpired() {
		r.HTTPRequest.Header.Set(tokenHeader, ec2Token.token)
		return
	}
	output, err := t.client.getToken(r.Context(), t.configuredTTL)
	if err != nil {
		if requestFailureError, ok := err.(awserr.RequestFailure); ok {
			switch requestFailureError.StatusCode() {
			case http.StatusForbidden, http.StatusNotFound, http.StatusMethodNotAllowed:
				atomic.StoreUint32(&t.disabled, 1)
			case http.StatusBadRequest:
				r.Error = requestFailureError
			}
			if e, ok := requestFailureError.OrigErr().(awserr.Error); ok {
				if e.Code() == request.ErrCodeRequestError {
					atomic.StoreUint32(&t.disabled, 1)
				}
			}
		}
		return
	}
	newToken := ec2Token{
		token: output.Token,
	}
	newToken.SetExpiration(time.Now().Add(output.TTL), ttlExpirationWindow)
	t.token.Store(newToken)
	if ec2Token, ok := t.token.Load().(ec2Token); ok {
		r.HTTPRequest.Header.Set(tokenHeader, ec2Token.token)
	}
}
fetchTokenHandler fetches token for EC2Metadata service client by default.
package ec2metadata
import (
	"net/http"
	"sync/atomic"
	"time"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/request"
)
type tokenProvider struct {
	client        *EC2Metadata
	token         atomic.Value
	configuredTTL time.Duration
	disabled      uint32
}
type ec2Token struct {
	token string
	credentials.Expiry
}
func newTokenProvider(c *EC2Metadata, duration time.Duration) *tokenProvider {
	return &tokenProvider{client: c, configuredTTL: duration}
}