util/golang/service/service.go (125 lines of code) (raw):

package service import ( "bytes" "crypto/hmac" "crypto/md5" "crypto/sha1" "encoding/base64" "encoding/hex" "hash" "io" "net/url" "sort" "strings" "time" "github.com/alibabacloud-go/tea/tea" ) func GetDate() *string { gmt := time.FixedZone("GMT", 0) return tea.String(time.Now().In(gmt).Format("2006-01-02T15:04:05Z")) } func GetContentMD5(content *string) *string { sum := md5.Sum([]byte(tea.StringValue(content))) return tea.String(hex.EncodeToString(sum[:])) } func GetSignature(request *tea.Request, accessKeyId, accessKeySecret *string) *string { sign := "OPENSEARCH " + tea.StringValue(accessKeyId) + ":" + getSignature(request, tea.StringValue(accessKeySecret)) return tea.String(sign) } func Append(in []*string, item *string) []*string { in = append(in, item) return in } func Keys(m map[string]interface{}) []*string { keys := make([]*string, 0) for key := range m { keys = append(keys, tea.String(key)) } return keys } func Join(in []*string, spearator *string) *string { res := strings.Join(tea.StringSliceValue(in), tea.StringValue(spearator)) return tea.String(res) } func MapToString(in map[string]*string, spearator *string) *string { res := "" for key, value := range in { res += key + tea.StringValue(spearator) + tea.StringValue(value) + "," } return tea.String(res) } func getSignature(request *tea.Request, accessKeySecret string) string { resource := tea.StringValue(request.Pathname) if !strings.Contains(resource, "?") && len(request.Query) > 0 { resource += "?" } queryKeys := make([]string, len(request.Query)) for k,_ := range request.Query { queryKeys = append(queryKeys, k) } sort.Strings(queryKeys) for _, key := range queryKeys { value := request.Query[key] if value != nil { tmp := url.QueryEscape(tea.StringValue(value)) tmp = strings.ReplaceAll(tmp, "'", "%27") tmp = strings.ReplaceAll(tmp, "+", "%20") if strings.HasSuffix(resource, "?") { resource = resource + key + "=" + tmp } else { resource = resource + "&" + key + "=" + tmp } } } return getSignedStr(request, resource, accessKeySecret) } // Sorter defines the key-value structure for storing the sorted data in signHeader. type Sorter struct { Keys []string Vals []string } // newSorter is an additional function for function Sign. func newSorter(m map[string]string) *Sorter { hs := &Sorter{ Keys: make([]string, 0, len(m)), Vals: make([]string, 0, len(m)), } for k, v := range m { hs.Keys = append(hs.Keys, k) hs.Vals = append(hs.Vals, v) } return hs } // Sort is an additional function for function SignHeader. func (hs *Sorter) Sort() { sort.Sort(hs) } // Len is an additional function for function SignHeader. func (hs *Sorter) Len() int { return len(hs.Vals) } // Less is an additional function for function SignHeader. func (hs *Sorter) Less(i, j int) bool { return bytes.Compare([]byte(hs.Keys[i]), []byte(hs.Keys[j])) < 0 } // Swap is an additional function for function SignHeader. func (hs *Sorter) Swap(i, j int) { hs.Vals[i], hs.Vals[j] = hs.Vals[j], hs.Vals[i] hs.Keys[i], hs.Keys[j] = hs.Keys[j], hs.Keys[i] } func getSignedStr(req *tea.Request, canonicalizedResource, accessKeySecret string) string { // Find out the "x-oss-"'s address in header of the request temp := make(map[string]string) for k, v := range req.Headers { if strings.HasPrefix(strings.ToLower(k), "x-opensearch-") { temp[strings.ToLower(k)] = tea.StringValue(v) } } hs := newSorter(temp) // Sort the temp by the ascending order hs.Sort() // Get the canonicalizedOSSHeaders canonicalizedOSSHeaders := "" for i := range hs.Keys { canonicalizedOSSHeaders += hs.Keys[i] + ":" + hs.Vals[i] + "\n" } // Give other parameters values // when sign URL, date is expires date := tea.StringValue(req.Headers["Date"]) contentType := tea.StringValue(req.Headers["Content-Type"]) contentMd5 := tea.StringValue(req.Headers["Content-MD5"]) signStr := tea.StringValue(req.Method) + "\n" + contentMd5 + "\n" + contentType + "\n" + date + "\n" + canonicalizedOSSHeaders + canonicalizedResource h := hmac.New(func() hash.Hash { return sha1.New() }, []byte(accessKeySecret)) io.WriteString(h, signStr) signedStr := base64.StdEncoding.EncodeToString(h.Sum(nil)) return signedStr }