client.go raw

   1  // This file is auto-generated, don't edit it. Thanks.
   2  package utils
   3  
   4  import (
   5  	"bytes"
   6  	"crypto"
   7  	"crypto/hmac"
   8  	"crypto/md5"
   9  	"crypto/rand"
  10  	"crypto/rsa"
  11  	"crypto/sha1"
  12  	"crypto/sha256"
  13  	"crypto/x509"
  14  	"encoding/base64"
  15  	"encoding/hex"
  16  	"encoding/json"
  17  	"encoding/pem"
  18  	"errors"
  19  	"fmt"
  20  	"hash"
  21  	"io"
  22  	"io/ioutil"
  23  	mathRand "math/rand"
  24  	"net/http"
  25  	"net/textproto"
  26  	"net/url"
  27  	"reflect"
  28  	"runtime"
  29  	"sort"
  30  	"strconv"
  31  	"strings"
  32  	"sync/atomic"
  33  	"time"
  34  
  35  	models "github.com/alibabacloud-go/darabonba-openapi/v2/models"
  36  	"github.com/alibabacloud-go/tea/dara"
  37  	"github.com/tjfoc/gmsm/sm3"
  38  )
  39  
  40  var defaultUserAgent = fmt.Sprintf("AlibabaCloud (%s; %s) Golang/%s Core/%s TeaDSL/2", runtime.GOOS, runtime.GOARCH, strings.Trim(runtime.Version(), "go"), "0.01")
  41  var seqId int64 = 0
  42  var processStartTime int64 = time.Now().UnixNano() / 1e6
  43  
  44  const (
  45  	PEM_BEGIN = "-----BEGIN RSA PRIVATE KEY-----\n"
  46  	PEM_END   = "\n-----END RSA PRIVATE KEY-----"
  47  )
  48  
  49  type Config = models.Config
  50  type GlobalParameters = models.GlobalParameters
  51  type Params = models.Params
  52  type OpenApiRequest = models.OpenApiRequest
  53  
  54  type Sorter struct {
  55  	Keys []string
  56  	Vals []string
  57  }
  58  
  59  func newSorter(m map[string]string) *Sorter {
  60  	hs := &Sorter{
  61  		Keys: make([]string, 0, len(m)),
  62  		Vals: make([]string, 0, len(m)),
  63  	}
  64  
  65  	for k, v := range m {
  66  		hs.Keys = append(hs.Keys, k)
  67  		hs.Vals = append(hs.Vals, v)
  68  	}
  69  	return hs
  70  }
  71  
  72  // Sort is an additional function for function SignHeader.
  73  func (hs *Sorter) Sort() {
  74  	sort.Sort(hs)
  75  }
  76  
  77  // Len is an additional function for function SignHeader.
  78  func (hs *Sorter) Len() int {
  79  	return len(hs.Vals)
  80  }
  81  
  82  // Less is an additional function for function SignHeader.
  83  func (hs *Sorter) Less(i, j int) bool {
  84  	return bytes.Compare([]byte(hs.Keys[i]), []byte(hs.Keys[j])) < 0
  85  }
  86  
  87  // Swap is an additional function for function SignHeader.
  88  func (hs *Sorter) Swap(i, j int) {
  89  	hs.Vals[i], hs.Vals[j] = hs.Vals[j], hs.Vals[i]
  90  	hs.Keys[i], hs.Keys[j] = hs.Keys[j], hs.Keys[i]
  91  }
  92  
  93  // Description:
  94  //
  95  // This is for OpenApi Util
  96  
  97  // Description:
  98  //
  99  // # Convert all params of body other than type of readable into content
 100  //
 101  // @param body - source Model
 102  //
 103  // @param content - target Model
 104  //
 105  // @return void
 106  func Convert(body interface{}, content interface{}) {
 107  	res := make(map[string]interface{})
 108  	val := reflect.ValueOf(body).Elem()
 109  	dataType := val.Type()
 110  	for i := 0; i < dataType.NumField(); i++ {
 111  		field := dataType.Field(i)
 112  		name, _ := field.Tag.Lookup("json")
 113  		name = strings.Split(name, ",omitempty")[0]
 114  		_, ok := val.Field(i).Interface().(io.Reader)
 115  		if !ok {
 116  			res[name] = val.Field(i).Interface()
 117  		}
 118  	}
 119  	byt, _ := json.Marshal(res)
 120  	json.Unmarshal(byt, content)
 121  }
 122  
 123  // Description:
 124  //
 125  // # Get throttling param
 126  //
 127  // @param the - response headers
 128  //
 129  // @return time left
 130  func GetThrottlingTimeLeft(headers map[string]*string) (_result *int64) {
 131  	rateLimitForUserApi := headers["x-ratelimit-user-api"]
 132  	rateLimitForUser := headers["x-ratelimit-user"]
 133  	timeLeftForUserApi := getTimeLeft(rateLimitForUserApi)
 134  	timeLeftForUser := getTimeLeft(rateLimitForUser)
 135  	if dara.Int64Value(timeLeftForUserApi) > dara.Int64Value(timeLeftForUser) {
 136  		return timeLeftForUserApi
 137  	} else {
 138  		return timeLeftForUser
 139  	}
 140  }
 141  
 142  // Description:
 143  //
 144  // # Hash the raw data with signatureAlgorithm
 145  //
 146  // @param raw - hashing data
 147  //
 148  // @param signatureAlgorithm - the autograph method
 149  //
 150  // @return hashed bytes
 151  func Hash(raw []byte, signatureAlgorithm *string) (_result []byte) {
 152  	signType := dara.StringValue(signatureAlgorithm)
 153  	if signType == "ACS3-HMAC-SHA256" || signType == "ACS3-RSA-SHA256" {
 154  		h := sha256.New()
 155  		h.Write(raw)
 156  		return h.Sum(nil)
 157  	} else if signType == "ACS3-HMAC-SM3" {
 158  		h := sm3.New()
 159  		h.Write(raw)
 160  		return h.Sum(nil)
 161  	}
 162  	return nil
 163  }
 164  
 165  func getGID() uint64 {
 166  	// https://blog.sgmansfield.com/2015/12/goroutine-ids/
 167  	b := make([]byte, 64)
 168  	b = b[:runtime.Stack(b, false)]
 169  	b = bytes.TrimPrefix(b, []byte("goroutine "))
 170  	b = b[:bytes.IndexByte(b, ' ')]
 171  	n, _ := strconv.ParseUint(string(b), 10, 64)
 172  	return n
 173  }
 174  
 175  // Description:
 176  //
 177  // # Generate a nonce string
 178  //
 179  // @return the nonce string
 180  func GetNonce() (_result *string) {
 181  	routineId := getGID()
 182  	currentTime := time.Now().UnixNano() / 1e6
 183  	seq := atomic.AddInt64(&seqId, 1)
 184  	randNum := mathRand.Int63()
 185  	msg := fmt.Sprintf("%d-%d-%d-%d-%d", processStartTime, routineId, currentTime, seq, randNum)
 186  	h := md5.New()
 187  	h.Write([]byte(msg))
 188  	ret := hex.EncodeToString(h.Sum(nil))
 189  	return &ret
 190  }
 191  
 192  // Description:
 193  //
 194  // # Get the string to be signed according to request
 195  //
 196  // @param request - which contains signed messages
 197  //
 198  // @return the signed string
 199  func GetStringToSign(request *dara.Request) (_result *string) {
 200  	return dara.String(getStringToSign(request))
 201  }
 202  
 203  func getStringToSign(request *dara.Request) string {
 204  	// sort QueryParams by key
 205  	var queryKeys []string
 206  	resource := dara.StringValue(request.Pathname)
 207  	queryParams := request.Query
 208  	for key := range queryParams {
 209  		queryKeys = append(queryKeys, key)
 210  	}
 211  	sort.Strings(queryKeys)
 212  	tmp := ""
 213  	for i := 0; i < len(queryKeys); i++ {
 214  		queryKey := queryKeys[i]
 215  		v := dara.StringValue(queryParams[queryKey])
 216  		if v != "" {
 217  			tmp = tmp + "&" + queryKey + "=" + v
 218  		} else {
 219  			tmp = tmp + "&" + queryKey
 220  		}
 221  	}
 222  	if tmp != "" {
 223  		tmp = strings.TrimLeft(tmp, "&")
 224  		resource = resource + "?" + tmp
 225  	}
 226  	return getSignedStr(request, resource)
 227  }
 228  
 229  func getSignedStr(req *dara.Request, canonicalizedResource string) string {
 230  	temp := make(map[string]string)
 231  
 232  	for k, v := range req.Headers {
 233  		if strings.HasPrefix(strings.ToLower(k), "x-acs-") {
 234  			temp[strings.ToLower(k)] = dara.StringValue(v)
 235  		}
 236  	}
 237  	hs := newSorter(temp)
 238  
 239  	// Sort the temp by the ascending order
 240  	hs.Sort()
 241  
 242  	// Get the canonicalizedOSSHeaders
 243  	canonicalizedOSSHeaders := ""
 244  	for i := range hs.Keys {
 245  		canonicalizedOSSHeaders += hs.Keys[i] + ":" + hs.Vals[i] + "\n"
 246  	}
 247  
 248  	// Give other parameters values
 249  	// when sign URL, date is expires
 250  	date := dara.StringValue(req.Headers["date"])
 251  	accept := dara.StringValue(req.Headers["accept"])
 252  	contentType := dara.StringValue(req.Headers["content-type"])
 253  	contentMd5 := dara.StringValue(req.Headers["content-md5"])
 254  
 255  	signStr := dara.StringValue(req.Method) + "\n" + accept + "\n" + contentMd5 + "\n" + contentType + "\n" + date + "\n" + canonicalizedOSSHeaders + canonicalizedResource
 256  	return signStr
 257  }
 258  
 259  // Description:
 260  //
 261  // # Get signature according to stringToSign, secret
 262  //
 263  // @param stringToSign - the signed string
 264  //
 265  // @param secret - accesskey secret
 266  //
 267  // @return the signature
 268  func GetROASignature(stringToSign *string, secret *string) (_result *string) {
 269  	h := hmac.New(func() hash.Hash { return sha1.New() }, []byte(dara.StringValue(secret)))
 270  	io.WriteString(h, dara.StringValue(stringToSign))
 271  	signedStr := base64.StdEncoding.EncodeToString(h.Sum(nil))
 272  	return dara.String(signedStr)
 273  }
 274  
 275  // Description:
 276  //
 277  // # Parse filter into a form string
 278  //
 279  // @param filter - object
 280  //
 281  // @return the string
 282  func ToForm(filter map[string]interface{}) (_result *string) {
 283  	tmp := make(map[string]interface{})
 284  	byt, _ := json.Marshal(filter)
 285  	d := json.NewDecoder(bytes.NewReader(byt))
 286  	d.UseNumber()
 287  	_ = d.Decode(&tmp)
 288  
 289  	result := make(map[string]*string)
 290  	for key, value := range tmp {
 291  		filterValue := reflect.ValueOf(value)
 292  		flatRepeatedList(filterValue, result, key)
 293  	}
 294  
 295  	m := make(map[string]interface{})
 296  	for key, value := range result {
 297  		m[key] = dara.StringValue(value)
 298  	}
 299  	return dara.String(dara.ToFormString(m))
 300  }
 301  
 302  func flatRepeatedList(dataValue reflect.Value, result map[string]*string, prefix string) {
 303  	if !dataValue.IsValid() {
 304  		return
 305  	}
 306  
 307  	dataType := dataValue.Type()
 308  	if dataType.Kind().String() == "slice" {
 309  		handleRepeatedParams(dataValue, result, prefix)
 310  	} else if dataType.Kind().String() == "map" {
 311  		handleMap(dataValue, result, prefix)
 312  	} else {
 313  		result[prefix] = dara.String(fmt.Sprintf("%v", dataValue.Interface()))
 314  	}
 315  }
 316  
 317  func handleRepeatedParams(repeatedFieldValue reflect.Value, result map[string]*string, prefix string) {
 318  	if repeatedFieldValue.IsValid() && !repeatedFieldValue.IsNil() {
 319  		for m := 0; m < repeatedFieldValue.Len(); m++ {
 320  			elementValue := repeatedFieldValue.Index(m)
 321  			key := prefix + "." + strconv.Itoa(m+1)
 322  			fieldValue := reflect.ValueOf(elementValue.Interface())
 323  			if fieldValue.Kind().String() == "map" {
 324  				handleMap(fieldValue, result, key)
 325  			} else {
 326  				result[key] = dara.String(fmt.Sprintf("%v", fieldValue.Interface()))
 327  			}
 328  		}
 329  	}
 330  }
 331  
 332  func handleMap(valueField reflect.Value, result map[string]*string, prefix string) {
 333  	var byt []byte
 334  	if valueField.IsValid() && valueField.String() != "" {
 335  		valueFieldType := valueField.Type()
 336  		if valueFieldType.Kind().String() == "map" {
 337  			byt, _ = json.Marshal(valueField.Interface())
 338  			cache := make(map[string]interface{})
 339  			d := json.NewDecoder(bytes.NewReader(byt))
 340  			d.UseNumber()
 341  			_ = d.Decode(&cache)
 342  			for key, value := range cache {
 343  				pre := ""
 344  				if prefix != "" {
 345  					pre = prefix + "." + key
 346  				} else {
 347  					pre = key
 348  				}
 349  				fieldValue := reflect.ValueOf(value)
 350  				flatRepeatedList(fieldValue, result, pre)
 351  			}
 352  		}
 353  	}
 354  }
 355  
 356  // Description:
 357  //
 358  // # Get timestamp
 359  //
 360  // @return the timestamp string
 361  func GetTimestamp() (_result *string) {
 362  	gmt := time.FixedZone("GMT", 0)
 363  	return dara.String(time.Now().In(gmt).Format("2006-01-02T15:04:05Z"))
 364  }
 365  
 366  // Description:
 367  //
 368  // # Get UTC string
 369  //
 370  // @return the UTC string
 371  func GetDateUTCString() (_result *string) {
 372  	return dara.String(time.Now().UTC().Format(http.TimeFormat))
 373  }
 374  
 375  // Description:
 376  //
 377  // Parse filter into a object which's type is map[string]string
 378  //
 379  // @param filter - query param
 380  //
 381  // @return the object
 382  func Query(filter interface{}) (_result map[string]*string) {
 383  	tmp := make(map[string]interface{})
 384  	byt, _ := json.Marshal(filter)
 385  	d := json.NewDecoder(bytes.NewReader(byt))
 386  	d.UseNumber()
 387  	_ = d.Decode(&tmp)
 388  
 389  	result := make(map[string]*string)
 390  	for key, value := range tmp {
 391  		filterValue := reflect.ValueOf(value)
 392  		flatRepeatedList(filterValue, result, key)
 393  	}
 394  
 395  	return result
 396  }
 397  
 398  // Description:
 399  //
 400  // # Get signature according to signedParams, method and secret
 401  //
 402  // @param signedParams - params which need to be signed
 403  //
 404  // @param method - http method e.g. GET
 405  //
 406  // @param secret - AccessKeySecret
 407  //
 408  // @return the signature
 409  func GetRPCSignature(signedParams map[string]*string, method *string, secret *string) (_result *string) {
 410  	stringToSign := buildRpcStringToSign(signedParams, dara.StringValue(method))
 411  	signature := sign(stringToSign, dara.StringValue(secret), "&")
 412  	return dara.String(signature)
 413  }
 414  
 415  // Description:
 416  //
 417  // # Parse array into a string with specified style
 418  //
 419  // @param array - the array
 420  //
 421  // @param prefix - the prefix string
 422  //
 423  // @return the string
 424  func ArrayToStringWithSpecifiedStyle(array interface{}, prefix *string, style *string) (_result *string) {
 425  	if dara.IsNil(array) {
 426  		return dara.String("")
 427  	}
 428  
 429  	sty := dara.StringValue(style)
 430  	if sty == "repeatList" {
 431  		tmp := map[string]interface{}{
 432  			dara.StringValue(prefix): array,
 433  		}
 434  		return flatRepeatList(tmp)
 435  	} else if sty == "simple" || sty == "spaceDelimited" || sty == "pipeDelimited" {
 436  		return flatArray(array, sty)
 437  	} else if sty == "json" {
 438  		return dara.String(dara.Stringify(array))
 439  	}
 440  	return dara.String("")
 441  }
 442  
 443  // Description:
 444  //
 445  // # Get the authorization
 446  //
 447  // @param request - request params
 448  //
 449  // @param signatureAlgorithm - the autograph method
 450  //
 451  // @param payload - the hashed request
 452  //
 453  // @param accessKey - the accessKey string
 454  //
 455  // @param accessKeySecret - the accessKeySecret string
 456  //
 457  // @return authorization string
 458  func GetAuthorization(request *dara.Request, signatureAlgorithm *string, payload *string, accessKey *string, accessKeySecret *string) (_result *string) {
 459  	canonicalURI := dara.StringValue(request.Pathname)
 460  	if canonicalURI == "" {
 461  		canonicalURI = "/"
 462  	}
 463  
 464  	canonicalURI = strings.Replace(canonicalURI, "+", "%20", -1)
 465  	canonicalURI = strings.Replace(canonicalURI, "*", "%2A", -1)
 466  	canonicalURI = strings.Replace(canonicalURI, "%7E", "~", -1)
 467  
 468  	method := dara.StringValue(request.Method)
 469  	canonicalQueryString := getCanonicalQueryString(request.Query)
 470  	canonicalheaders, signedHeaders := getCanonicalHeaders(request.Headers)
 471  
 472  	canonicalRequest := method + "\n" + canonicalURI + "\n" + canonicalQueryString + "\n" + canonicalheaders + "\n" +
 473  		strings.Join(signedHeaders, ";") + "\n" + dara.StringValue(payload)
 474  	signType := dara.StringValue(signatureAlgorithm)
 475  	StringToSign := signType + "\n" + hex.EncodeToString(Hash([]byte(canonicalRequest), signatureAlgorithm))
 476  	signature := hex.EncodeToString(SignatureMethod(dara.StringValue(accessKeySecret), StringToSign, signType))
 477  	auth := signType + " Credential=" + dara.StringValue(accessKey) + ",SignedHeaders=" +
 478  		strings.Join(signedHeaders, ";") + ",Signature=" + signature
 479  	return dara.String(auth)
 480  }
 481  
 482  func GetUserAgent(userAgent *string) (_result *string) {
 483  	if userAgent != nil && dara.StringValue(userAgent) != "" {
 484  		return dara.String(defaultUserAgent + " " + dara.StringValue(userAgent))
 485  	}
 486  	return dara.String(defaultUserAgent)
 487  }
 488  
 489  func SignatureMethod(secret, source, signatureAlgorithm string) []byte {
 490  	if signatureAlgorithm == "ACS3-HMAC-SHA256" {
 491  		h := hmac.New(sha256.New, []byte(secret))
 492  		h.Write([]byte(source))
 493  		return h.Sum(nil)
 494  	} else if signatureAlgorithm == "ACS3-HMAC-SM3" {
 495  		h := hmac.New(sm3.New, []byte(secret))
 496  		h.Write([]byte(source))
 497  		return h.Sum(nil)
 498  	} else if signatureAlgorithm == "ACS3-RSA-SHA256" {
 499  		return rsaSign(source, secret)
 500  	}
 501  	return nil
 502  }
 503  
 504  func flatRepeatList(filter map[string]interface{}) (_result *string) {
 505  	tmp := make(map[string]interface{})
 506  	byt, _ := json.Marshal(filter)
 507  	d := json.NewDecoder(bytes.NewReader(byt))
 508  	d.UseNumber()
 509  	_ = d.Decode(&tmp)
 510  
 511  	result := make(map[string]*string)
 512  	for key, value := range tmp {
 513  		filterValue := reflect.ValueOf(value)
 514  		flatRepeatedList(filterValue, result, key)
 515  	}
 516  
 517  	res := make(map[string]string)
 518  	for k, v := range result {
 519  		res[k] = dara.StringValue(v)
 520  	}
 521  	hs := newSorter(res)
 522  
 523  	hs.Sort()
 524  
 525  	// Get the canonicalizedOSSHeaders
 526  	t := ""
 527  	for i := range hs.Keys {
 528  		if i == len(hs.Keys)-1 {
 529  			t += hs.Keys[i] + "=" + hs.Vals[i]
 530  		} else {
 531  			t += hs.Keys[i] + "=" + hs.Vals[i] + "&&"
 532  		}
 533  	}
 534  	return dara.String(t)
 535  }
 536  
 537  func flatArray(array interface{}, sty string) *string {
 538  	t := reflect.ValueOf(array)
 539  	strs := make([]string, 0)
 540  	for i := 0; i < t.Len(); i++ {
 541  		tmp := t.Index(i)
 542  		if tmp.Kind() == reflect.Ptr || tmp.Kind() == reflect.Interface {
 543  			tmp = tmp.Elem()
 544  		}
 545  
 546  		if tmp.Kind() == reflect.Ptr {
 547  			tmp = tmp.Elem()
 548  		}
 549  		if tmp.Kind() == reflect.String {
 550  			strs = append(strs, tmp.String())
 551  		} else {
 552  			inter := tmp.Interface()
 553  			byt, _ := json.Marshal(inter)
 554  			strs = append(strs, string(byt))
 555  		}
 556  	}
 557  	str := ""
 558  	if sty == "simple" {
 559  		str = strings.Join(strs, ",")
 560  	} else if sty == "spaceDelimited" {
 561  		str = strings.Join(strs, " ")
 562  	} else if sty == "pipeDelimited" {
 563  		str = strings.Join(strs, "|")
 564  	}
 565  	return dara.String(str)
 566  }
 567  
 568  func buildRpcStringToSign(signedParam map[string]*string, method string) (stringToSign string) {
 569  	signParams := make(map[string]string)
 570  	for key, value := range signedParam {
 571  		signParams[key] = dara.StringValue(value)
 572  	}
 573  
 574  	stringToSign = getUrlFormedMap(signParams)
 575  	stringToSign = strings.Replace(stringToSign, "+", "%20", -1)
 576  	stringToSign = strings.Replace(stringToSign, "*", "%2A", -1)
 577  	stringToSign = strings.Replace(stringToSign, "%7E", "~", -1)
 578  	stringToSign = url.QueryEscape(stringToSign)
 579  	stringToSign = method + "&%2F&" + stringToSign
 580  	return
 581  }
 582  
 583  func getUrlFormedMap(source map[string]string) (urlEncoded string) {
 584  	urlEncoder := url.Values{}
 585  	for key, value := range source {
 586  		urlEncoder.Add(key, value)
 587  	}
 588  	urlEncoded = urlEncoder.Encode()
 589  	return
 590  }
 591  
 592  func sign(stringToSign, accessKeySecret, secretSuffix string) string {
 593  	secret := accessKeySecret + secretSuffix
 594  	signedBytes := shaHmac1(stringToSign, secret)
 595  	signedString := base64.StdEncoding.EncodeToString(signedBytes)
 596  	return signedString
 597  }
 598  
 599  func shaHmac1(source, secret string) []byte {
 600  	key := []byte(secret)
 601  	hmac := hmac.New(sha1.New, key)
 602  	hmac.Write([]byte(source))
 603  	return hmac.Sum(nil)
 604  }
 605  
 606  func getTimeLeft(rateLimit *string) (_result *int64) {
 607  	if rateLimit != nil {
 608  		pairs := strings.Split(dara.StringValue(rateLimit), ",")
 609  		for _, pair := range pairs {
 610  			kv := strings.Split(pair, ":")
 611  			if len(kv) == 2 {
 612  				key, value := kv[0], kv[1]
 613  				if key == "TimeLeft" {
 614  					timeLeftValue, err := strconv.ParseInt(value, 10, 64)
 615  					if err != nil {
 616  						return nil
 617  					}
 618  					return dara.Int64(timeLeftValue)
 619  				}
 620  			}
 621  		}
 622  	}
 623  	return nil
 624  }
 625  
 626  func rsaSign(content, secret string) []byte {
 627  	h := crypto.SHA256.New()
 628  	h.Write([]byte(content))
 629  	hashed := h.Sum(nil)
 630  	priv, err := parsePrivateKey(secret)
 631  	if err != nil {
 632  		return nil
 633  	}
 634  	sign, err := rsa.SignPKCS1v15(rand.Reader, priv, crypto.SHA256, hashed)
 635  	if err != nil {
 636  		return nil
 637  	}
 638  	return sign
 639  }
 640  
 641  func parsePrivateKey(privateKey string) (*rsa.PrivateKey, error) {
 642  	privateKey = formatPrivateKey(privateKey)
 643  	block, _ := pem.Decode([]byte(privateKey))
 644  	if block == nil {
 645  		return nil, errors.New("PrivateKey is invalid")
 646  	}
 647  	priKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
 648  	if err != nil {
 649  		return nil, err
 650  	}
 651  	switch priKey.(type) {
 652  	case *rsa.PrivateKey:
 653  		return priKey.(*rsa.PrivateKey), nil
 654  	default:
 655  		return nil, nil
 656  	}
 657  }
 658  
 659  func formatPrivateKey(privateKey string) string {
 660  	if !strings.HasPrefix(privateKey, PEM_BEGIN) {
 661  		privateKey = PEM_BEGIN + privateKey
 662  	}
 663  
 664  	if !strings.HasSuffix(privateKey, PEM_END) {
 665  		privateKey += PEM_END
 666  	}
 667  	return privateKey
 668  }
 669  
 670  func getCanonicalHeaders(headers map[string]*string) (string, []string) {
 671  	tmp := make(map[string]string)
 672  	tmpHeader := http.Header{}
 673  	for k, v := range headers {
 674  		if strings.HasPrefix(strings.ToLower(k), "x-acs-") || strings.ToLower(k) == "host" ||
 675  			strings.ToLower(k) == "content-type" {
 676  			tmp[strings.ToLower(k)] = strings.TrimSpace(dara.StringValue(v))
 677  			tmpHeader.Add(strings.ToLower(k), strings.TrimSpace(dara.StringValue(v)))
 678  		}
 679  	}
 680  	hs := newSorter(tmp)
 681  
 682  	// Sort the temp by the ascending order
 683  	hs.Sort()
 684  	canonicalheaders := ""
 685  	for _, key := range hs.Keys {
 686  		vals := tmpHeader[textproto.CanonicalMIMEHeaderKey(key)]
 687  		sort.Strings(vals)
 688  		canonicalheaders += key + ":" + strings.Join(vals, ",") + "\n"
 689  	}
 690  
 691  	return canonicalheaders, hs.Keys
 692  }
 693  
 694  func getCanonicalQueryString(query map[string]*string) string {
 695  	canonicalQueryString := ""
 696  	if dara.IsNil(query) {
 697  		return canonicalQueryString
 698  	}
 699  	tmp := make(map[string]string)
 700  	for k, v := range query {
 701  		tmp[k] = dara.StringValue(v)
 702  	}
 703  
 704  	hs := newSorter(tmp)
 705  
 706  	// Sort the temp by the ascending order
 707  	hs.Sort()
 708  	for i := range hs.Keys {
 709  		if hs.Vals[i] != "" {
 710  			canonicalQueryString += "&" + hs.Keys[i] + "=" + url.QueryEscape(hs.Vals[i])
 711  		} else {
 712  			canonicalQueryString += "&" + hs.Keys[i] + "="
 713  		}
 714  	}
 715  	canonicalQueryString = strings.Replace(canonicalQueryString, "+", "%20", -1)
 716  	canonicalQueryString = strings.Replace(canonicalQueryString, "*", "%2A", -1)
 717  	canonicalQueryString = strings.Replace(canonicalQueryString, "%7E", "~", -1)
 718  
 719  	if canonicalQueryString != "" {
 720  		canonicalQueryString = strings.TrimLeft(canonicalQueryString, "&")
 721  	}
 722  	return canonicalQueryString
 723  }
 724  
 725  func ParseToMap(in interface{}) map[string]interface{} {
 726  	if dara.IsNil(in) {
 727  		return nil
 728  	}
 729  
 730  	tmp := make(map[string]interface{})
 731  	byt, _ := json.Marshal(in)
 732  	d := json.NewDecoder(bytes.NewReader(byt))
 733  	d.UseNumber()
 734  	err := d.Decode(&tmp)
 735  	if err != nil {
 736  		return nil
 737  	}
 738  	return tmp
 739  }
 740  
 741  func GetEndpointRules(product, regionId, endpointType, network, suffix *string) (_result *string, _err error) {
 742  	if dara.StringValue(endpointType) == "regional" {
 743  		if dara.StringValue(regionId) == "" {
 744  			_err = fmt.Errorf("RegionId is empty, please set a valid RegionId")
 745  			return dara.String(""), _err
 746  		}
 747  		_result = dara.String(strings.Replace("<product><suffix><network>.<region_id>.aliyuncs.com",
 748  			"<region_id>", dara.StringValue(regionId), 1))
 749  	} else {
 750  		_result = dara.String("<product><suffix><network>.aliyuncs.com")
 751  	}
 752  	_result = dara.String(strings.Replace(dara.StringValue(_result),
 753  		"<product>", strings.ToLower(dara.StringValue(product)), 1))
 754  	if dara.StringValue(network) == "" || dara.StringValue(network) == "public" {
 755  		_result = dara.String(strings.Replace(dara.StringValue(_result), "<network>", "", 1))
 756  	} else {
 757  		_result = dara.String(strings.Replace(dara.StringValue(_result),
 758  			"<network>", "-"+dara.StringValue(network), 1))
 759  	}
 760  	if dara.StringValue(suffix) == "" {
 761  		_result = dara.String(strings.Replace(dara.StringValue(_result), "<suffix>", "", 1))
 762  	} else {
 763  		_result = dara.String(strings.Replace(dara.StringValue(_result),
 764  			"<suffix>", "-"+dara.StringValue(suffix), 1))
 765  	}
 766  	return _result, nil
 767  }
 768  
 769  func ToArray(in interface{}) []map[string]interface{} {
 770  	tmp := make([]map[string]interface{}, 0)
 771  	if dara.IsNil(in) {
 772  		return nil
 773  	}
 774  	byt, _ := json.Marshal(in)
 775  	d := json.NewDecoder(bytes.NewReader(byt))
 776  	d.UseNumber()
 777  	err := d.Decode(&tmp)
 778  	if err != nil {
 779  		return nil
 780  	}
 781  	return tmp
 782  }
 783  
 784  func GetEndpoint(endpoint *string, server *bool, endpointType *string) *string {
 785  	if dara.StringValue(endpointType) == "internal" {
 786  		strs := strings.Split(dara.StringValue(endpoint), ".")
 787  		strs[0] += "-internal"
 788  		endpoint = dara.String(strings.Join(strs, "."))
 789  	}
 790  	if dara.BoolValue(server) && dara.StringValue(endpointType) == "accelerate" {
 791  		return dara.String("oss-accelerate.aliyuncs.com")
 792  	}
 793  
 794  	return endpoint
 795  }
 796  
 797  func toJSONString(a interface{}) *string {
 798  	switch v := a.(type) {
 799  	case *string:
 800  		return v
 801  	case string:
 802  		return dara.String(v)
 803  	case []byte:
 804  		return dara.String(string(v))
 805  	case io.Reader:
 806  		byt, err := ioutil.ReadAll(v)
 807  		if err != nil {
 808  			return nil
 809  		}
 810  		return dara.String(string(byt))
 811  	}
 812  	byt := bytes.NewBuffer([]byte{})
 813  	jsonEncoder := json.NewEncoder(byt)
 814  	jsonEncoder.SetEscapeHTML(false)
 815  	if err := jsonEncoder.Encode(a); err != nil {
 816  		return nil
 817  	}
 818  	return dara.String(string(bytes.TrimSpace(byt.Bytes())))
 819  }
 820  
 821  func StringifyMapValue(a map[string]interface{}) map[string]*string {
 822  	res := make(map[string]*string)
 823  	for key, value := range a {
 824  		if value != nil {
 825  			res[key] = toJSONString(value)
 826  		}
 827  	}
 828  	return res
 829  }
 830