func getStringToSign(canonicalRequest string, dateTime string) (string, error) {
	hexEncodeReq, errHexEncode := hexEncodeSHA256Hash([]byte(canonicalRequest))
	if errHexEncode != nil {
		return "", errHexEncode
	}
	return strings.Join([]string{algorithm, dateTime, hexEncodeReq}, lineSeparator), nil
}
construct string to sign and return
package util
import (
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"errors"
	"fmt"
	log "github.com/sirupsen/logrus"
	"io/ioutil"
	"net/http"
	"net/url"
	"reflect"
	"sort"
	"strings"
)
const (
	separator     string = "/"
	lineSeparator string = "\n"
	DateFormat    string = "20060102T150405Z"
	algorithm     string = "SDK-HMAC-SHA256"
	DateHeader    string = "x-sdk-date"
)
type Sign struct {
	SecretKey *[]byte
	AccessKey string
}
func (sig *Sign) GetAuthorizationValueWithSign(req *http.Request) (string, error) {
	signature, errGetSignature := sig.GetSignature(req)
	if errGetSignature != nil {
		return "", errGetSignature
	}
	return getAuthorizationHeaderValue(signature, sig.AccessKey, getSignedHeaders(req)), nil
}
func (sig *Sign) GetSignature(req *http.Request) (string, error) {
	if req == nil {
		return "", errors.New("request is nil")
	}
	canonicalRequest, errGetCanonicalRequest := getCanonicalRequest(req)
	if errGetCanonicalRequest != nil {
		return "", errGetCanonicalRequest
	}
	stringToSign, errGetStringToSign := getStringToSign(canonicalRequest, req.Header.Get(DateHeader))
	if errGetStringToSign != nil {
		return "", errGetStringToSign
	}
	signature, errCalculateSignature := calculateSignature(stringToSign, sig.SecretKey)
	if errCalculateSignature != nil {
		return "", errCalculateSignature
	}
	return signature, nil
}
func getCanonicalRequest(req *http.Request) (string, error) {  
	method := req.Method
	uri := getCanonicalURI(req)
	query := getCanonicalQueryString(req)
	headersReq := getCanonicalHeaders(req)
	headersSign := getSignedHeaders(req)
	hexEncodeBody, errGetRequestBodyHash := getRequestBodyHash(req)
	if errGetRequestBodyHash != nil {
		return "", errGetRequestBodyHash
	}
	return strings.Join([]string{method, uri, query, headersReq, headersSign, hexEncodeBody}, lineSeparator), nil
}
func getCanonicalURI(req *http.Request) string {
	paths := strings.Split(req.URL.Path, separator)
	var uris []string
	for _, path := range paths {
		if path == "" || path == "." || path == ".." {
			continue
		}
		uris = append(uris, url.QueryEscape(path))
	}
	canonicalUri := separator + strings.Join(uris, separator)
	if strings.HasSuffix(canonicalUri, separator) {
		return canonicalUri
	} else {
		return canonicalUri + separator
	}
}
func getCanonicalQueryString(req *http.Request) string {
	var params []string
	for key, values := range req.URL.Query() {
		for _, value := range values {
			params = append(params, url.QueryEscape(key) + "=" + url.QueryEscape(value))
		}
	}
	sort.Strings(params)
	return strings.Join(params, "&")
}
func getCanonicalHeaders(req *http.Request) string {
	var headers []string
	for key, values := range req.Header {
		sort.Strings(values)
		var val []string
		for _, value := range values {
			val = append(val, strings.TrimSpace(value))
		}
		headers = append(headers, strings.ToLower(key) + ":" + strings.Join(val, ","))
	}
	sort.Strings(headers)
	return strings.Join(headers, lineSeparator) + lineSeparator
}
func getSignedHeaders(req *http.Request) string {
	var headers []string
	for key := range req.Header {
		headers = append(headers, strings.ToLower(key))
	}
	sort.Strings(headers)
	return strings.Join(headers, ";")
}
func getRequestBodyHash(req *http.Request) (string, error) {
	reqBody, errGetRequestBody := getRequestBody(req)
	if errGetRequestBody != nil {
		return "", errGetRequestBody
	}
	hexEncode, errHexEncode := hexEncodeSHA256Hash(reqBody)
	if errHexEncode != nil {
		return "", errHexEncode
	}
	return hexEncode, nil
}
func getRequestBody(req *http.Request) ([]byte, error) {
	if req.Body == nil {
		return []byte(""), nil
	}
	body, errReadAll := ioutil.ReadAll(req.Body)
	if errReadAll != nil {
		return []byte(""), errReadAll
	}
	req.Body = ioutil.NopCloser(bytes.NewBuffer(body))
	return body, nil
}
func hexEncodeSHA256Hash(bytes []byte) (string, error) {
	hash := sha256.New()
	_, errWrite := hash.Write(bytes)
	if errWrite != nil {
		return "", errWrite
	}
	return hex.EncodeToString(hash.Sum(nil)), nil
}