func (this *Credentials) expired() bool {
	if this.Expiration.IsZero() {
		return false
	}
	expireTime := this.Expiration.Add(-4 * time.Minute)
	if expireTime.Before(time.Now()) {
		return true
	} else {
		return false
	}
}
expired checks to see if the temporary credentials from an IAM role are
within 4 minutes of expiration (The IAM documentation says that new keys
will be provisioned 5 minutes before the old keys expire). Credentials
that do not have an Expiration cannot expire.
package awsauth
import (
	"net/http"
	"net/url"
	"time"
)
type Credentials struct {
	AccessKeyID     string
	SecretAccessKey string
	SecurityToken   string `json:"Token"`
	Expiration      time.Time
}
func Sign(request *http.Request, credentials ...Credentials) *http.Request {
	service, _ := serviceAndRegion(request.URL.Host)
	signVersion := awsSignVersion[service]
	switch signVersion {
	case 2:
		return Sign2(request, credentials...)
	case 3:
		return Sign3(request, credentials...)
	case 4:
		return Sign4(request, credentials...)
	case -1:
		return SignS3(request, credentials...)
	}
	return nil
}
func Sign4(request *http.Request, credentials ...Credentials) *http.Request {
	keys := chooseKeys(credentials)
	if keys.SecurityToken != "" {
		request.Header.Set("X-Amz-Security-Token", keys.SecurityToken)
	}
	prepareRequestV4(request)
	meta := new(metadata)
	hashedCanonReq := hashedCanonicalRequestV4(request, meta)
	stringToSign := stringToSignV4(request, hashedCanonReq, meta)
	signingKey := signingKeyV4(keys.SecretAccessKey, meta.date, meta.region, meta.service)
	signature := signatureV4(signingKey, stringToSign)
	request.Header.Set("Authorization", buildAuthHeaderV4(signature, meta, keys))
	return request
}
func Sign3(request *http.Request, credentials ...Credentials) *http.Request {
	keys := chooseKeys(credentials)
	if keys.SecurityToken != "" {
		request.Header.Set("X-Amz-Security-Token", keys.SecurityToken)
	}
	prepareRequestV3(request)
	stringToSign := stringToSignV3(request)
	signature := signatureV3(stringToSign, keys)
	request.Header.Set("X-Amzn-Authorization", buildAuthHeaderV3(signature, keys))
	return request
}
func Sign2(request *http.Request, credentials ...Credentials) *http.Request {
	keys := chooseKeys(credentials)
	if keys.SecurityToken != "" {
		values := url.Values{}
		values.Set("SecurityToken", keys.SecurityToken)
		augmentRequestQuery(request, values)
	}
	prepareRequestV2(request, keys)
	stringToSign := stringToSignV2(request)
	signature := signatureV2(stringToSign, keys)
	values := url.Values{}
	values.Set("Signature", signature)
	augmentRequestQuery(request, values)
	return request
}
func SignS3(request *http.Request, credentials ...Credentials) *http.Request {
	keys := chooseKeys(credentials)
	if keys.SecurityToken != "" {
		request.Header.Set("X-Amz-Security-Token", keys.SecurityToken)
	}
	prepareRequestS3(request)
	stringToSign := stringToSignS3(request)
	signature := signatureS3(stringToSign, keys)
	authHeader := "AWS " + keys.AccessKeyID + ":" + signature
	request.Header.Set("Authorization", authHeader)
	return request
}
func SignS3Url(request *http.Request, expire time.Time, credentials ...Credentials) *http.Request {
	keys := chooseKeys(credentials)
	stringToSign := stringToSignS3Url("GET", expire, request.URL.Path)
	signature := signatureS3(stringToSign, keys)
	query := request.URL.Query()
	query.Set("AWSAccessKeyId", keys.AccessKeyID)
	query.Set("Signature", signature)
	query.Set("Expires", timeToUnixEpochString(expire))
	request.URL.RawQuery = query.Encode()
	return request
}