func()

in oss/signer/v4.go [109:209]


func (s *SignerV4) calcCanonicalRequest(signingCtx *SigningContext, additionalHeaders []string) string {
	request := signingCtx.Request
	/*
		Canonical Request
		HTTP Verb + "\n" +
		Canonical URI + "\n" +
		Canonical Query String + "\n" +
		Canonical Headers + "\n" +
		Additional Headers + "\n" +
		Hashed PayLoad
	*/

	//Canonical Uri
	uri := "/"
	if signingCtx.Bucket != nil {
		uri += *signingCtx.Bucket + "/"
	}
	if signingCtx.Key != nil {
		uri += *signingCtx.Key
	}
	canonicalUri := escapePath(uri, false)

	//Canonical Query
	query := strings.Replace(request.URL.RawQuery, "+", "%20", -1)
	values := make(map[string]string)
	var params []string
	for query != "" {
		var key string
		key, query, _ = strings.Cut(query, "&")
		if key == "" {
			continue
		}
		key, value, _ := strings.Cut(key, "=")
		values[key] = value
		params = append(params, key)
	}
	sort.Strings(params)
	var buf strings.Builder
	for _, k := range params {
		if buf.Len() > 0 {
			buf.WriteByte('&')
		}
		buf.WriteString(k)
		if len(values[k]) > 0 {
			buf.WriteByte('=')
			buf.WriteString(values[k])
		}
	}
	canonicalQuery := buf.String()

	//Canonical Headers
	var headers []string
	buf.Reset()
	addHeadersMap := make(map[string]bool)
	for _, k := range additionalHeaders {
		addHeadersMap[strings.ToLower(k)] = true
	}
	for k := range request.Header {
		lowk := strings.ToLower(k)
		if isDefaultSignedHeader(lowk) {
			headers = append(headers, lowk)
		} else if _, ok := addHeadersMap[lowk]; ok {
			headers = append(headers, lowk)
		}
	}
	sort.Strings(headers)
	for _, k := range headers {
		headerValues := make([]string, len(request.Header.Values(k)))
		for i, v := range request.Header.Values(k) {
			headerValues[i] = strings.TrimSpace(v)
		}
		buf.WriteString(k)
		buf.WriteString(":")
		buf.WriteString(strings.Join(headerValues, ","))
		buf.WriteString("\n")
	}
	canonicalHeaders := buf.String()

	//Additional Headers
	canonicalAdditionalHeaders := strings.Join(additionalHeaders, ";")

	hashPayload := unsignedPayload
	if val := request.Header.Get(contentSha256Header); val != "" {
		hashPayload = val
	}

	buf.Reset()
	buf.WriteString(request.Method)
	buf.WriteString("\n")
	buf.WriteString(canonicalUri)
	buf.WriteString("\n")
	buf.WriteString(canonicalQuery)
	buf.WriteString("\n")
	buf.WriteString(canonicalHeaders)
	buf.WriteString("\n")
	buf.WriteString(canonicalAdditionalHeaders)
	buf.WriteString("\n")
	buf.WriteString(hashPayload)

	return buf.String()
}