tencent/COS.go

136 lines
3.4 KiB
Go
Raw Permalink Normal View History

2024-12-20 18:35:59 +08:00
package tencent
import (
2025-01-14 14:34:54 +08:00
"bytes"
"context"
"errors"
"io"
"net/http"
"net/url"
2024-12-20 18:35:59 +08:00
"strings"
2025-01-14 14:34:54 +08:00
"time"
2024-12-20 18:35:59 +08:00
2025-01-14 14:34:54 +08:00
"github.com/ssgo/u"
"github.com/tencentyun/cos-go-sdk-v5"
2024-12-20 18:35:59 +08:00
sts "github.com/tencentyun/qcloud-cos-sts-sdk/go"
)
type Cos struct {
2025-01-14 14:34:54 +08:00
client *cos.Client
baseUrl string
bucket string
appId string
region string
2024-12-20 18:35:59 +08:00
}
2025-01-14 14:34:54 +08:00
func GetCos(bucket string) (*Cos, error) {
2024-12-20 18:35:59 +08:00
bConf := conf.Cos[bucket]
2025-01-14 14:34:54 +08:00
if bConf == nil {
return nil, errors.New("bucket not found")
}
2024-12-20 18:35:59 +08:00
a := strings.Split(bConf.Bucket, "-")
2025-01-14 14:34:54 +08:00
baseUrl := "https://" + bConf.Bucket + ".cos." + bConf.Region + ".myqcloud.com"
bUrl, _ := url.Parse(baseUrl)
2024-12-20 18:35:59 +08:00
return &Cos{
2025-01-14 14:34:54 +08:00
client: cos.NewClient(&cos.BaseURL{BucketURL: bUrl}, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: bConf.SecretId,
SecretKey: bConf.SecretKey,
},
}),
baseUrl: baseUrl,
bucket: bConf.Bucket,
appId: a[len(a)-1],
region: bConf.Region,
}, nil
2024-12-20 18:35:59 +08:00
}
type CosToken struct {
sts.Credentials
Bucket string
Region string
}
var defaultAllowPath = "/"
func (c *Cos) GetToken(allowPath *string) (*CosToken, error) {
if allowPath == nil {
allowPath = &defaultAllowPath
}
2025-01-14 14:34:54 +08:00
stsCli := sts.NewClient(conf.Cos[c.bucket].SecretId, conf.Cos[c.bucket].SecretKey, nil)
crt, err := stsCli.GetCredential(&sts.CredentialOptions{
2024-12-20 18:35:59 +08:00
DurationSeconds: 3600,
Region: c.region,
Policy: &sts.CredentialPolicy{
Statement: []sts.CredentialPolicyStatement{{
Action: []string{"name/cos:PostObject", "name/cos:PutObject", "name/cos:InitiateMultipartUpload", "name/cos:ListMultipartUploads", "name/cos:ListParts", "name/cos:UploadPart", "name/cos:CompleteMultipartUpload"},
Effect: "allow",
Resource: []string{"qcs::cos:" + c.region + ":uid/" + c.appId + ":" + c.bucket + *allowPath + "*"},
}},
},
})
if err == nil {
return &CosToken{
Credentials: *crt.Credentials,
Bucket: c.bucket,
Region: c.region,
}, nil
}
return nil, err
}
2025-01-14 14:34:54 +08:00
func (c *Cos) Put(name string, data any) (string, error) {
var err error
if v, ok := data.(string); ok {
if u.FileExists(v) {
buf := u.ReadFileBytesN(v)
_, err = c.client.Object.Put(context.Background(), name, bytes.NewReader(buf), nil)
} else {
_, err = c.client.Object.Put(context.Background(), name, strings.NewReader(v), nil)
}
} else if v, ok := data.([]byte); ok {
_, err = c.client.Object.Put(context.Background(), name, bytes.NewReader(v), nil)
} else {
_, err = c.client.Object.Put(context.Background(), name, strings.NewReader(u.Json(data)), nil)
}
if err == nil {
return c.baseUrl + "/" + name, nil
} else {
return "", err
}
}
func (c *Cos) Get(name string) ([]byte, error) {
r, err := c.client.Object.Get(context.Background(), name, nil)
if err != nil {
return nil, err
}
defer r.Body.Close()
return io.ReadAll(r.Body)
}
func (c *Cos) MakeUrl(name string, expires *int64) (string, error) {
expiresTime := time.Second * 300
if expires != nil && *expires > 0 {
expiresTime = time.Millisecond * time.Duration(*expires)
}
r, err := c.client.Object.GetPresignedURL2(context.Background(), "GET", name, expiresTime, nil)
if err != nil {
return "", err
}
return r.String(), nil
}
func (c *Cos) Delete(name string) error {
_, err := c.client.Object.Delete(context.Background(), name)
return err
}
func (c *Cos) Head(name string) (*http.Header, error) {
r, err := c.client.Object.Head(context.Background(), name, nil)
if err != nil {
return nil, err
}
return &r.Header, nil
}