func()

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
}