package upyun import ( "crypto/hmac" "crypto/md5" "crypto/sha1" "encoding/base64" "encoding/json" "fmt" "pychr/global" "strings" "time" ) const ( effectiveDuration = time.Minute * 30 ) type FormAPIToken struct { Bucket string Method string Authorization string XUpYunExpire int64 Policy string Date string } type Policy struct { Bucket string `json:"bucket"` SaveKey string `json:"save-key"` Expiration int64 `json:"expiration"` // ContentMD5 string `json:"content-md5"` } func makeSaveKey() string { return "/{year}/{mon}/{day}/upload_{random32}{.suffix}" } func makePolicy(bucket, saveKey string) (string, int64) { expiration := time.Now().Add(effectiveDuration).Unix() obj := Policy{ Bucket: bucket, SaveKey: saveKey, Expiration: expiration, // ContentMD5: content-md5, } str, err := json.Marshal(&obj) if err != nil { return "", 0 } sEnc := base64.StdEncoding.EncodeToString([]byte(str)) return sEnc, expiration } func md5Str(s string) string { return fmt.Sprintf("%x", md5.Sum([]byte(s))) } func makeRFC1123Date(d time.Time) string { utc := d.UTC().Format(time.RFC1123) return strings.Replace(utc, "UTC", "GMT", -1) } func base64ToStr(b []byte) string { return base64.StdEncoding.EncodeToString(b) } func sign(key, secret, method, uri, date, policy, md5 string) string { mac := hmac.New(sha1.New, []byte(secret)) elems := []string{} for _, v := range []string{method, uri, date, policy, md5} { if v != "" { elems = append(elems, v) } } value := strings.Join(elems, "&") mac.Write([]byte(value)) signStr := base64ToStr(mac.Sum(nil)) return "UPYUN " + key + ":" + signStr } func GetUpyunToken(method, saveKey string) (r FormAPIToken, err error) { method = strings.ToUpper(method) date := makeRFC1123Date(time.Now()) policy, expiration := makePolicy(global.GVA_CONFIG.CDN.Bucket, saveKey) authorization := sign(global.GVA_CONFIG.CDN.Bucket, md5Str(global.GVA_CONFIG.CDN.Password), method, "/"+global.GVA_CONFIG.CDN.Bucket, "", policy, "") r.Bucket = global.GVA_CONFIG.CDN.Bucket r.Method = method r.XUpYunExpire = expiration r.Authorization = authorization r.Policy = policy r.Date = date return }