github.com/astaxie/beego@v1.12.3/logs/alils/signature.go (about)

     1  package alils
     2  
     3  import (
     4  	"crypto/hmac"
     5  	"crypto/sha1"
     6  	"encoding/base64"
     7  	"fmt"
     8  	"net/url"
     9  	"sort"
    10  	"strings"
    11  	"time"
    12  )
    13  
    14  // GMT location
    15  var gmtLoc = time.FixedZone("GMT", 0)
    16  
    17  // NowRFC1123 returns now time in RFC1123 format with GMT timezone,
    18  // eg. "Mon, 02 Jan 2006 15:04:05 GMT".
    19  func nowRFC1123() string {
    20  	return time.Now().In(gmtLoc).Format(time.RFC1123)
    21  }
    22  
    23  // signature calculates a request's signature digest.
    24  func signature(project *LogProject, method, uri string,
    25  	headers map[string]string) (digest string, err error) {
    26  	var contentMD5, contentType, date, canoHeaders, canoResource string
    27  	var slsHeaderKeys sort.StringSlice
    28  
    29  	// SignString = VERB + "\n"
    30  	//              + CONTENT-MD5 + "\n"
    31  	//              + CONTENT-TYPE + "\n"
    32  	//              + DATE + "\n"
    33  	//              + CanonicalizedSLSHeaders + "\n"
    34  	//              + CanonicalizedResource
    35  
    36  	if val, ok := headers["Content-MD5"]; ok {
    37  		contentMD5 = val
    38  	}
    39  
    40  	if val, ok := headers["Content-Type"]; ok {
    41  		contentType = val
    42  	}
    43  
    44  	date, ok := headers["Date"]
    45  	if !ok {
    46  		err = fmt.Errorf("Can't find 'Date' header")
    47  		return
    48  	}
    49  
    50  	// Calc CanonicalizedSLSHeaders
    51  	slsHeaders := make(map[string]string, len(headers))
    52  	for k, v := range headers {
    53  		l := strings.TrimSpace(strings.ToLower(k))
    54  		if strings.HasPrefix(l, "x-sls-") {
    55  			slsHeaders[l] = strings.TrimSpace(v)
    56  			slsHeaderKeys = append(slsHeaderKeys, l)
    57  		}
    58  	}
    59  
    60  	sort.Sort(slsHeaderKeys)
    61  	for i, k := range slsHeaderKeys {
    62  		canoHeaders += k + ":" + slsHeaders[k]
    63  		if i+1 < len(slsHeaderKeys) {
    64  			canoHeaders += "\n"
    65  		}
    66  	}
    67  
    68  	// Calc CanonicalizedResource
    69  	u, err := url.Parse(uri)
    70  	if err != nil {
    71  		return
    72  	}
    73  
    74  	canoResource += url.QueryEscape(u.Path)
    75  	if u.RawQuery != "" {
    76  		var keys sort.StringSlice
    77  
    78  		vals := u.Query()
    79  		for k := range vals {
    80  			keys = append(keys, k)
    81  		}
    82  
    83  		sort.Sort(keys)
    84  		canoResource += "?"
    85  		for i, k := range keys {
    86  			if i > 0 {
    87  				canoResource += "&"
    88  			}
    89  
    90  			for _, v := range vals[k] {
    91  				canoResource += k + "=" + v
    92  			}
    93  		}
    94  	}
    95  
    96  	signStr := method + "\n" +
    97  		contentMD5 + "\n" +
    98  		contentType + "\n" +
    99  		date + "\n" +
   100  		canoHeaders + "\n" +
   101  		canoResource
   102  
   103  	// Signature = base64(hmac-sha1(UTF8-Encoding-Of(SignString),AccessKeySecret))
   104  	mac := hmac.New(sha1.New, []byte(project.AccessKeySecret))
   105  	_, err = mac.Write([]byte(signStr))
   106  	if err != nil {
   107  		return
   108  	}
   109  	digest = base64.StdEncoding.EncodeToString(mac.Sum(nil))
   110  	return
   111  }