Compare commits

..

No commits in common. "23138f4e06222f96664482b27bcd523a640d7f4d" and "1722fa82f87e970ed1a4040c54d6d2dcd78ce6b7" have entirely different histories.

View File

@ -5,14 +5,9 @@ import (
"errors"
"fmt"
"gitea.bvbej.com/bvbej/base-golang/pkg/md5"
"github.com/qiniu/go-sdk/v7/auth"
"github.com/qiniu/go-sdk/v7/cdn"
"github.com/qiniu/go-sdk/v7/storagev2/credentials"
"github.com/qiniu/go-sdk/v7/storagev2/downloader"
"github.com/qiniu/go-sdk/v7/storagev2/http_client"
"github.com/qiniu/go-sdk/v7/storagev2/objects"
"github.com/qiniu/go-sdk/v7/storagev2/uploader"
"github.com/qiniu/go-sdk/v7/storagev2/uptoken"
"gitea.bvbej.com/bvbej/base-golang/tool"
"github.com/qiniu/go-sdk/v7/auth/qbox"
"github.com/qiniu/go-sdk/v7/storage"
"github.com/tidwall/gjson"
"io"
"net/http"
@ -22,37 +17,33 @@ import (
"time"
)
type Qhash string
const (
QSha1 Qhash = "sha1"
QSha256 Qhash = "sha256"
)
var _ QiNiu = (*qiNiu)(nil)
type QiNiu interface {
SetDefaultUploadTokenTTL(duration time.Duration)
GetUploadToken() (string, error)
GetCallbackUploadToken(callbackURL string) (string, error)
TimestampSecuritySign(urlStr string, ttl time.Duration) (string, error)
UploadFile(key, localFile, callbackURL string) (*PutRet, error)
GetPrivateURL(key string, ttl time.Duration) (string, error)
i()
SetDefaultUploadTokenTTL(ttl uint64)
GetCallbackUploadToken(ttl uint64, callbackURL string) string
GetUploadToken(ttl uint64) string
GetPrivateURL(key string, ttl uint64) string
VerifyCallback(req *http.Request) (bool, error)
GetFileInfo(key string) (*objects.ObjectDetails, error)
UploadFile(key, localFile string) (*PutRet, error)
ResumeUploadFile(key, localFile string) (*PutRet, error)
DelFile(key string) error
ListFiles(keyPrefix, marker string, limit uint64) ([]objects.ObjectDetails, error)
GetFileHash(path string, qhash Qhash) (hash string, err error)
TimestampSecuritySign(path string, ttl time.Duration) string
GetFileInfo(key string) *storage.FileInfo
ListFiles(prefix, delimiter, marker string, limit int) (entries []storage.ListItem, commonPrefixes []string, nextMarker string, hasNext bool, err error)
GetFileHash(path, qhash string) (hash string, err error)
}
type qiNiu struct {
mac *qbox.Mac
bucketManager *storage.BucketManager
conf *storage.Config
bucket string
domain string
securityKey string
credentials *auth.Credentials
bucketManager *objects.Bucket
md5 md5.MD5
uploadTokenTTL time.Duration
uploadTokenTTL uint64
}
type PutRet struct {
@ -66,75 +57,78 @@ type PutRet struct {
}
func New(accessKey, secretKey, bucket, domain, securityKey string) QiNiu {
cred := credentials.NewCredentials(accessKey, secretKey)
objectsManager := objects.NewObjectsManager(&objects.ObjectsManagerOptions{
Options: http_client.Options{Credentials: cred},
})
mac := qbox.NewMac(accessKey, secretKey)
conf := &storage.Config{
UseHTTPS: true, //是否使用https域名
UseCdnDomains: false, //上传是否使用CDN上传加速
}
return &qiNiu{
mac: mac,
bucketManager: storage.NewBucketManager(mac, conf),
bucket: bucket,
domain: domain,
securityKey: securityKey,
credentials: cred,
bucketManager: objectsManager.Bucket(bucket),
conf: conf,
md5: md5.New(),
uploadTokenTTL: time.Second * 3600,
uploadTokenTTL: 3600,
}
}
func (q *qiNiu) SetDefaultUploadTokenTTL(duration time.Duration) {
q.uploadTokenTTL = duration
func (q *qiNiu) i() {}
func (q *qiNiu) SetDefaultUploadTokenTTL(ttl uint64) {
q.uploadTokenTTL = ttl
}
func (q *qiNiu) GetUploadToken() (string, error) {
putPolicy, err := uptoken.NewPutPolicy(q.bucket, time.Now().Add(q.uploadTokenTTL))
if err != nil {
return "", err
func (q *qiNiu) GetUploadToken(ttl uint64) string {
putPolicy := storage.PutPolicy{
Scope: q.bucket,
Expires: ttl,
}
return uptoken.NewSigner(putPolicy, q.credentials).GetUpToken(context.Background())
return putPolicy.UploadToken(q.mac)
}
func (q *qiNiu) GetCallbackUploadToken(callbackURL string) (string, error) {
putPolicy, err := uptoken.NewPutPolicy(q.bucket, time.Now().Add(q.uploadTokenTTL))
if err != nil {
return "", err
func (q *qiNiu) GetCallbackUploadToken(ttl uint64, callbackURL string) string {
putPolicy := storage.PutPolicy{
Scope: q.bucket,
CallbackURL: callbackURL,
CallbackBody: `{"key":"$(key)","hash":"$(etag)","fname":"$(fname)","fsize":"$(fsize)","ext":"$(ext)","unique":"$(x:unique)","user":"$(x:user)"}`,
CallbackBodyType: "application/json",
Expires: ttl,
}
putPolicy.SetCallbackUrl(callbackURL).
SetCallbackBody(`{"key":"$(key)","hash":"$(etag)","fname":"$(fname)","fsize":"$(fsize)","ext":"$(ext)","unique":"$(x:unique)","user":"$(x:user)"}`).
SetCallbackBodyType("application/json")
return uptoken.NewSigner(putPolicy, q.credentials).GetUpToken(context.Background())
return putPolicy.UploadToken(q.mac)
}
func (q *qiNiu) TimestampSecuritySign(urlStr string, ttl time.Duration) (string, error) {
deadline := time.Now().Add(ttl).Unix()
tUrl, err := cdn.CreateTimestampAntileechURL(urlStr, q.securityKey, deadline)
if err != nil {
return "", err
}
return tUrl, nil
func (q *qiNiu) GetPrivateURL(key string, ttl uint64) string {
deadline := time.Now().Add(time.Second * time.Duration(ttl)).Unix()
return storage.MakePrivateURL(q.mac, q.domain, key, deadline)
}
func (q *qiNiu) UploadFile(key, localFile, callbackURL string) (*PutRet, error) {
putPolicy, err := uptoken.NewPutPolicy(q.bucket, time.Now().Add(q.uploadTokenTTL))
if err != nil {
return nil, err
func (q *qiNiu) VerifyCallback(req *http.Request) (bool, error) {
return q.mac.VerifyCallback(req)
}
putPolicy.SetCallbackUrl(callbackURL).
SetCallbackBody(`{"key":"$(key)","hash":"$(etag)","fname":"$(fname)","fsize":"$(fsize)","ext":"$(ext)","unique":"$(x:unique)","user":"$(x:user)"}`).
SetCallbackBodyType("application/json")
ret := &PutRet{}
func (q *qiNiu) UploadFile(key, localFile string) (*PutRet, error) {
upToken := q.GetUploadToken(q.uploadTokenTTL)
//构建表单上传的对象
formUploader := storage.NewFormUploader(q.conf)
//请求参数
filename := path.Base(key)
fileSuffix := path.Ext(key)
filePrefix := filename[0 : len(filename)-len(fileSuffix)]
uploadManager := uploader.NewUploadManager(&uploader.UploadManagerOptions{})
err = uploadManager.UploadFile(context.Background(), localFile, &uploader.ObjectOptions{
UpToken: uptoken.NewSigner(putPolicy, q.credentials),
ObjectName: &key,
CustomVars: map[string]string{
"unique": filePrefix,
"user": "api",
putExtra := &storage.PutExtra{
Params: map[string]string{
"x:unique": filePrefix,
"x:user": "-",
},
}, ret)
}
//自定义返回body
ret := new(PutRet)
err := formUploader.PutFile(context.Background(), ret, upToken, key, localFile, putExtra)
if err != nil {
return nil, err
}
@ -142,73 +136,84 @@ func (q *qiNiu) UploadFile(key, localFile, callbackURL string) (*PutRet, error)
return ret, nil
}
func (q *qiNiu) GetPrivateURL(key string, ttl time.Duration) (string, error) {
urlsProvider := downloader.SignURLsProvider(
downloader.NewStaticDomainBasedURLsProvider([]string{q.domain}),
downloader.NewCredentialsSigner(q.credentials),
&downloader.SignOptions{
TTL: ttl,
})
iter, err := urlsProvider.GetURLsIter(context.Background(), key, &downloader.GenerateOptions{BucketName: q.bucket})
if err != nil {
return "", err
}
res := url.URL{}
peek, err := iter.Peek(&res)
if err != nil {
return "", err
}
if peek {
return res.String(), nil
}
return "", errors.New("get private url false")
func (q *qiNiu) ResumeUploadFile(key, localFile string) (*PutRet, error) {
upToken := q.GetUploadToken(q.uploadTokenTTL)
//构建分片上传的对象
resumeUploader := storage.NewResumeUploaderV2(q.conf)
//请求参数
filename := path.Base(key)
fileSuffix := path.Ext(key)
filePrefix := filename[0 : len(filename)-len(fileSuffix)]
putExtra := &storage.RputV2Extra{
CustomVars: map[string]string{
"x:unique": filePrefix,
"x:user": "-",
},
}
func (q *qiNiu) VerifyCallback(req *http.Request) (bool, error) {
return q.credentials.VerifyCallback(req)
}
//自定义返回body
ret := new(PutRet)
func (q *qiNiu) GetFileInfo(key string) (*objects.ObjectDetails, error) {
objectInfo, err := q.bucketManager.Object(key).Stat().Call(context.Background())
err := resumeUploader.PutFile(context.Background(), ret, upToken, key, localFile, putExtra)
if err != nil {
return nil, err
}
return objectInfo, nil
return ret, nil
}
func (q *qiNiu) DelFile(key string) error {
err := q.bucketManager.Object(key).Delete().Call(context.Background())
err := q.bucketManager.Delete(q.bucket, key)
if err != nil {
return err
}
return nil
}
func (q *qiNiu) ListFiles(keyPrefix, marker string, limit uint64) ([]objects.ObjectDetails, error) {
iter := q.bucketManager.List(context.Background(), &objects.ListObjectsOptions{
Limit: &limit,
Prefix: keyPrefix,
Marker: marker,
})
defer func() {
_ = iter.Close()
}()
objectInfos := make([]objects.ObjectDetails, 0)
var objectInfo objects.ObjectDetails
for iter.Next(&objectInfo) {
objectInfos = append(objectInfos, objectInfo)
func (q *qiNiu) TimestampSecuritySign(path string, ttl time.Duration) string {
sep := "/"
path = strings.Trim(path, sep)
splits := strings.Split(path, sep)
for i, split := range splits {
splits[i] = url.QueryEscape(split)
}
if err := iter.Error(); err != nil {
return nil, err
}
return objectInfos, nil
path = sep + strings.Join(splits, sep)
unix := time.Now().Add(ttl).Unix()
hex := fmt.Sprintf("%x", unix)
encrypt := q.md5.Encrypt(q.securityKey + path + hex)
param := make(url.Values)
param.Set("sign", encrypt)
param.Set("t", hex)
return param.Encode()
}
func (q *qiNiu) GetFileHash(path string, qhash Qhash) (hash string, err error) {
sign, err := q.TimestampSecuritySign(path, time.Second*5)
if err != nil {
return "", err
func (q *qiNiu) GetFileInfo(key string) *storage.FileInfo {
fileInfo, sErr := q.bucketManager.Stat(q.bucket, key)
if sErr != nil {
return nil
}
return &fileInfo
}
func (q *qiNiu) ListFiles(prefix, delimiter, marker string, limit int) (entries []storage.ListItem,
commonPrefixes []string, nextMarker string, hasNext bool, err error) {
return q.bucketManager.ListFiles(q.bucket, prefix, delimiter, marker, limit)
}
func (q *qiNiu) GetFileHash(path, qhash string) (hash string, err error) {
if !tool.InArray(qhash, []string{"sha1", "md5", "sha256"}) {
return "", errors.New("qhash invalid")
}
sign := q.TimestampSecuritySign(path, time.Second*5)
addr := fmt.Sprintf("%s/%s?%s&qhash/%s", strings.TrimRight(q.domain, "/"), path, sign, qhash)
resp, err := http.Get(addr)