func (s *V4Signer) requestTime(req *http.Request) time.Time {
	date := req.Header.Get("x-amz-date")
	t, err := time.Parse(ISO8601BasicFormat, date)
	if err == nil {
		return t
	}
	t, err = time.Parse(http.TimeFormat, date)
	if err == nil {
		req.Header.Set("x-amz-date", t.Format(ISO8601BasicFormat))
		return t
	}
	date = req.Header.Get("date")
	t, err = time.Parse(http.TimeFormat, date)
	if err == nil {
		return t
	}
	t = time.Now().UTC()
	req.Header.Set("x-amz-date", t.Format(ISO8601BasicFormat))
	return t
}
/*
requestTime method will parse the time from the request "x-amz-date" or "date" headers.
If the "x-amz-date" header is present, that will take priority over the "date" header.
If neither header is defined or we are unable to parse either header as a valid date
then we will create a new "x-amz-date" header with the current time.
package aws
import (
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"path"
	"sort"
	"strings"
	"time"
)
type V2Signer struct {
	auth    *Auth
	service ServiceInfo
	host    string
}
var b64 = base64.StdEncoding
func NewV2Signer(auth *Auth, service ServiceInfo) (*V2Signer, error) {
	u, err := url.Parse(service.Endpoint)
	if err != nil {
		return nil, err
	}
	return &V2Signer{auth: auth, service: service, host: u.Host}, nil
}
func (s *V2Signer) Sign(method, path string, params map[string]string) {
	accessKey, secretKey, token := s.auth.Credentials()
	params["AWSAccessKeyId"] = accessKey
	params["SignatureVersion"] = "2"
	params["SignatureMethod"] = "HmacSHA256"
	if token != "" {
		params["SecurityToken"] = token
	}
	var keys, sarray []string
	for k, _ := range params {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, k := range keys {
		sarray = append(sarray, Encode(k)+"="+Encode(params[k]))
	}
	joined := strings.Join(sarray, "&")
	payload := method + "\n" + s.host + "\n" + path + "\n" + joined
	hash := hmac.New(sha256.New, []byte(secretKey))
	hash.Write([]byte(payload))
	signature := make([]byte, b64.EncodedLen(hash.Size()))
	b64.Encode(signature, hash.Sum(nil))
	params["Signature"] = string(signature)
}
const (
	ISO8601BasicFormat      = "20060102T150405Z"
	ISO8601BasicFormatShort = "20060102"
)
type Route53Signer struct {
	auth *Auth
}
func NewRoute53Signer(auth *Auth) *Route53Signer {
	return &Route53Signer{auth: auth}
}
func (s *Route53Signer) getCurrentDate() string {
	response, err := http.Get("https://route53.amazonaws.com/date")
	if err != nil {
		fmt.Print("Unable to get date from amazon: ", err)
		return ""
	}
	response.Body.Close()
	return response.Header.Get("Date")
}
func (s *Route53Signer) getHeaderAuthorize(message, secretKey string) string {
	hmacSha256 := hmac.New(sha256.New, []byte(secretKey))
	hmacSha256.Write([]byte(message))
	cryptedString := hmacSha256.Sum(nil)
	return base64.StdEncoding.EncodeToString(cryptedString)
}
func (s *Route53Signer) Sign(req *http.Request) {
	accessKey, secretKey, _ := s.auth.Credentials()
	date := s.getCurrentDate()
	authHeader := fmt.Sprintf("AWS3-HTTPS AWSAccessKeyId=%s,Algorithm=%s,Signature=%s",
		accessKey, "HmacSHA256", s.getHeaderAuthorize(date, secretKey))
	req.Header.Set("Host", req.Host)
	req.Header.Set("X-Amzn-Authorization", authHeader)
	req.Header.Set("X-Amz-Date", date)
	req.Header.Set("Content-Type", "application/xml")
}
type V4Signer struct {
	auth        *Auth
	serviceName string
	region      Region
}
func NewV4Signer(auth *Auth, serviceName string, region Region) *V4Signer {
	return &V4Signer{auth: auth, serviceName: serviceName, region: region}
}
func (s *V4Signer) Sign(req *http.Request) {
	accessKey, secretKey, token := s.auth.Credentials()
	if token != "" {
		req.Header.Set("X-Amz-Security-Token", token)
	}
	req.Header.Set("host", req.Host)                              
	t := s.requestTime(req)                                       
	creq := s.canonicalRequest(req)                               
	sts := s.stringToSign(t, creq)                                
	signature := s.signature(t, sts, secretKey)                   
	auth := s.authorization(req.Header, t, signature, accessKey)  
	req.Header.Set("Authorization", auth)                         
}