in signature_v4.go [51:105]
func (s *SignerV4) Sign(method, uri string, headers map[string]string, body []byte) error {
if s.region == "" {
return errSignerV4MissingRegion
}
uri, urlParams, err := s.parseUri(uri)
if err != nil {
return err
}
dateTime, ok := headers[HTTPHeaderLogDate]
if !ok {
return fmt.Errorf("can't find '%s' header", HTTPHeaderLogDate)
}
date := dateTime[:8]
// Host should not contain schema here.
if host, ok := headers[HTTPHeaderHost]; ok {
if strings.HasPrefix(host, "http://") {
headers[HTTPHeaderHost] = host[len("http://"):]
} else if strings.HasPrefix(host, "https://") {
headers[HTTPHeaderHost] = host[len("https://"):]
}
}
contentLength := len(body)
var sha256Payload string
if contentLength != 0 {
sha256Payload = fmt.Sprintf("%x", sha256.Sum256(body))
} else {
sha256Payload = emptyStringSha256
}
headers[HTTPHeaderLogContentSha256] = sha256Payload
headers[HTTPHeaderContentLength] = strconv.Itoa(contentLength)
// Canonical headers
signedHeadersStr, canonicalHeaderStr := s.buildCanonicalHeaders(headers)
// CanonicalRequest
canonReq := s.buildCanonicalRequest(method, uri, sha256Payload, canonicalHeaderStr, signedHeadersStr, urlParams)
scope := s.buildScope(date, s.region)
// SignKey + signMessage => signature
strToSign := s.buildSignMessage(canonReq, dateTime, scope)
key, err := s.buildSigningKey(s.accessKeySecret, s.region, date)
if err != nil {
return err
}
hash, err := s.hmacSha256([]byte(strToSign), key)
if err != nil {
return err
}
signature := hex.EncodeToString(hash)
headers[HTTPHeaderAuthorization] = s.buildAuthorization(s.accessKeyID, signature, scope)
return nil
}