diff --git a/COS.go b/COS.go index d373695..edb9c9a 100644 --- a/COS.go +++ b/COS.go @@ -1,31 +1,48 @@ package tencent import ( + "bytes" + "context" + "errors" + "io" + "net/http" + "net/url" "strings" + "time" + "github.com/ssgo/u" + "github.com/tencentyun/cos-go-sdk-v5" sts "github.com/tencentyun/qcloud-cos-sts-sdk/go" ) -func getCosClient(bucket string) *sts.Client { - return sts.NewClient(conf.Cos[bucket].SecretId, conf.Cos[bucket].SecretKey, nil) -} - type Cos struct { - client *sts.Client - bucket string - appId string - region string + client *cos.Client + baseUrl string + bucket string + appId string + region string } -func GetCos(bucket string) *Cos { +func GetCos(bucket string) (*Cos, error) { bConf := conf.Cos[bucket] - a := strings.Split(bConf.Bucket, "-") - return &Cos{ - client: getCosClient(bucket), - bucket: bConf.Bucket, - appId: a[len(a)-1], - region: bConf.Region, + if bConf == nil { + return nil, errors.New("bucket not found") } + a := strings.Split(bConf.Bucket, "-") + baseUrl := "https://" + bConf.Bucket + ".cos." + bConf.Region + ".myqcloud.com" + bUrl, _ := url.Parse(baseUrl) + return &Cos{ + 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 } type CosToken struct { @@ -40,7 +57,8 @@ func (c *Cos) GetToken(allowPath *string) (*CosToken, error) { if allowPath == nil { allowPath = &defaultAllowPath } - crt, err := c.client.GetCredential(&sts.CredentialOptions{ + stsCli := sts.NewClient(conf.Cos[c.bucket].SecretId, conf.Cos[c.bucket].SecretKey, nil) + crt, err := stsCli.GetCredential(&sts.CredentialOptions{ DurationSeconds: 3600, Region: c.region, Policy: &sts.CredentialPolicy{ @@ -60,3 +78,58 @@ func (c *Cos) GetToken(allowPath *string) (*CosToken, error) { } return nil, err } + +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 +} diff --git a/go.mod b/go.mod index b7f10fa..377c466 100644 --- a/go.mod +++ b/go.mod @@ -3,21 +3,26 @@ module apigo.cc/cloud/tencent go 1.18 require ( - apigo.cc/gojs v0.0.10 + apigo.cc/gojs v0.0.12 apigo.cc/gojs/console v0.0.2 github.com/ssgo/config v1.7.9 github.com/ssgo/u v1.7.13 + github.com/tencentyun/cos-go-sdk-v5 v0.7.60 github.com/tencentyun/qcloud-cos-sts-sdk v0.0.0-20241118064430-63a76784514f ) require ( + github.com/clbanning/mxj v1.8.4 // indirect github.com/dlclark/regexp2 v1.11.4 // indirect github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-sourcemap/sourcemap v2.1.4+incompatible // indirect + github.com/google/go-querystring v1.0.0 // indirect github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd // indirect + github.com/mitchellh/mapstructure v1.4.3 // indirect + github.com/mozillazg/go-httpheader v0.2.1 // indirect github.com/ssgo/log v1.7.7 // indirect github.com/ssgo/standard v1.7.7 // indirect - github.com/ssgo/tool v0.4.27 // indirect + github.com/ssgo/tool v0.4.28 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect