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