storage.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. package qiniu
  2. import (
  3. "context"
  4. "fmt"
  5. "git.bvbej.com/bvbej/base-golang/pkg/md5"
  6. "github.com/qiniu/go-sdk/v7/auth/qbox"
  7. "github.com/qiniu/go-sdk/v7/storage"
  8. "net/http"
  9. "net/url"
  10. "path"
  11. "strings"
  12. "time"
  13. )
  14. var _ QiNiu = (*qiNiu)(nil)
  15. type QiNiu interface {
  16. i()
  17. SetDefaultUploadTokenTTL(ttl uint64)
  18. GetCallbackUploadToken(ttl uint64, callbackURL string) string
  19. GetUploadToken(ttl uint64) string
  20. GetPrivateURL(key string, ttl uint64) string
  21. VerifyCallback(req *http.Request) (bool, error)
  22. UploadFile(key, localFile string) (*PutRet, error)
  23. ResumeUploadFile(key, localFile string) (*PutRet, error)
  24. DelFile(key string) error
  25. TimestampSecuritySign(path string, ttl time.Duration) string
  26. GetFileInfo(key string) *storage.FileInfo
  27. ListFiles(prefix, delimiter, marker string, limit int) (entries []storage.ListItem, commonPrefixes []string, nextMarker string, hasNext bool, err error)
  28. }
  29. type qiNiu struct {
  30. mac *qbox.Mac
  31. conf *storage.Config
  32. bucket string
  33. domain string
  34. securityKey string
  35. md5 md5.MD5
  36. uploadTokenTTL uint64
  37. }
  38. type PutRet struct {
  39. Key string `json:"key"`
  40. Hash string `json:"hash"`
  41. Fsize string `json:"fsize"`
  42. Fname string `json:"fname"`
  43. Ext string `json:"ext"`
  44. Unique string `json:"unique"`
  45. User string `json:"user"`
  46. }
  47. func New(accessKey, secretKey, bucket, domain, securityKey string) QiNiu {
  48. region, _ := storage.GetRegion(accessKey, bucket)
  49. return &qiNiu{
  50. mac: qbox.NewMac(accessKey, secretKey),
  51. bucket: bucket,
  52. domain: domain,
  53. securityKey: securityKey,
  54. conf: &storage.Config{
  55. Region: region, //空间所在的存储区域
  56. UseHTTPS: true, //是否使用https域名
  57. UseCdnDomains: true, //上传是否使用CDN上传加速
  58. },
  59. md5: md5.New(),
  60. uploadTokenTTL: 3600,
  61. }
  62. }
  63. func (q *qiNiu) i() {}
  64. func (q *qiNiu) SetDefaultUploadTokenTTL(ttl uint64) {
  65. q.uploadTokenTTL = ttl
  66. }
  67. func (q *qiNiu) GetUploadToken(ttl uint64) string {
  68. putPolicy := storage.PutPolicy{
  69. Scope: q.bucket,
  70. Expires: ttl,
  71. }
  72. return putPolicy.UploadToken(q.mac)
  73. }
  74. func (q *qiNiu) GetCallbackUploadToken(ttl uint64, callbackURL string) string {
  75. putPolicy := storage.PutPolicy{
  76. Scope: q.bucket,
  77. CallbackURL: callbackURL,
  78. CallbackBody: `{"key":"$(key)","hash":"$(etag)","fname":"$(fname)","fsize":"$(fsize)","ext":"$(ext)","unique":"$(x:unique)","user":"$(x:user)"}`,
  79. CallbackBodyType: "application/json",
  80. Expires: ttl,
  81. }
  82. return putPolicy.UploadToken(q.mac)
  83. }
  84. func (q *qiNiu) GetPrivateURL(key string, ttl uint64) string {
  85. deadline := time.Now().Add(time.Second * time.Duration(ttl)).Unix()
  86. return storage.MakePrivateURL(q.mac, q.domain, key, deadline)
  87. }
  88. func (q *qiNiu) VerifyCallback(req *http.Request) (bool, error) {
  89. return q.mac.VerifyCallback(req)
  90. }
  91. func (q *qiNiu) UploadFile(key, localFile string) (*PutRet, error) {
  92. upToken := q.GetUploadToken(q.uploadTokenTTL)
  93. //构建表单上传的对象
  94. formUploader := storage.NewFormUploader(q.conf)
  95. //请求参数
  96. filename := path.Base(key)
  97. fileSuffix := path.Ext(key)
  98. filePrefix := filename[0 : len(filename)-len(fileSuffix)]
  99. putExtra := &storage.PutExtra{
  100. Params: map[string]string{
  101. "x:unique": filePrefix,
  102. "x:user": "-",
  103. },
  104. }
  105. //自定义返回body
  106. ret := new(PutRet)
  107. err := formUploader.PutFile(context.Background(), ret, upToken, key, localFile, putExtra)
  108. if err != nil {
  109. return nil, err
  110. }
  111. return ret, nil
  112. }
  113. func (q *qiNiu) ResumeUploadFile(key, localFile string) (*PutRet, error) {
  114. upToken := q.GetUploadToken(q.uploadTokenTTL)
  115. //构建分片上传的对象
  116. resumeUploader := storage.NewResumeUploaderV2(q.conf)
  117. //请求参数
  118. filename := path.Base(key)
  119. fileSuffix := path.Ext(key)
  120. filePrefix := filename[0 : len(filename)-len(fileSuffix)]
  121. putExtra := &storage.RputV2Extra{
  122. CustomVars: map[string]string{
  123. "x:unique": filePrefix,
  124. "x:user": "-",
  125. },
  126. }
  127. //自定义返回body
  128. ret := new(PutRet)
  129. err := resumeUploader.PutFile(context.Background(), ret, upToken, key, localFile, putExtra)
  130. if err != nil {
  131. return nil, err
  132. }
  133. return ret, nil
  134. }
  135. func (q *qiNiu) DelFile(key string) error {
  136. bucketManager := storage.NewBucketManager(q.mac, q.conf)
  137. err := bucketManager.Delete(q.bucket, key)
  138. if err != nil {
  139. return err
  140. }
  141. return nil
  142. }
  143. func (q *qiNiu) TimestampSecuritySign(path string, ttl time.Duration) string {
  144. sep := "/"
  145. path = strings.Trim(path, sep)
  146. splits := strings.Split(path, sep)
  147. for i, split := range splits {
  148. splits[i] = url.QueryEscape(split)
  149. }
  150. path = sep + strings.Join(splits, sep)
  151. unix := time.Now().Add(ttl).Unix()
  152. hex := fmt.Sprintf("%x", unix)
  153. encrypt := q.md5.Encrypt(q.securityKey + path + hex)
  154. param := make(url.Values)
  155. param.Set("sign", encrypt)
  156. param.Set("t", hex)
  157. return param.Encode()
  158. }
  159. func (q *qiNiu) GetFileInfo(key string) *storage.FileInfo {
  160. bucketManager := storage.NewBucketManager(q.mac, q.conf)
  161. fileInfo, sErr := bucketManager.Stat(q.bucket, key)
  162. if sErr != nil {
  163. return nil
  164. }
  165. return &fileInfo
  166. }
  167. func (q *qiNiu) ListFiles(prefix, delimiter, marker string, limit int) (entries []storage.ListItem,
  168. commonPrefixes []string, nextMarker string, hasNext bool, err error) {
  169. bucketManager := storage.NewBucketManager(q.mac, q.conf)
  170. return bucketManager.ListFiles(q.bucket, prefix, delimiter, marker, limit)
  171. }