package storage import ( "context" "io" "net/http" "net/url" "strings" "time" "github.com/Masterminds/semver/v3" "github.com/rocboss/paopao-ce/internal/conf" "github.com/rocboss/paopao-ce/internal/core" "github.com/sirupsen/logrus" "github.com/tencentyun/cos-go-sdk-v5" ) var ( _ core.ObjectStorageService = (*cosServant)(nil) _ core.OssCreateService = (*cosCreateServant)(nil) _ core.OssCreateService = (*cosCreateTempDirServant)(nil) _ core.VersionInfo = (*cosServant)(nil) ) type cosCreateServant struct { client *cos.Client domain string } type cosCreateTempDirServant struct { client *cos.Client domain string bucketUrl string tempDir string } type cosServant struct { core.OssCreateService client *cos.Client domain string } func (s *cosCreateServant) PutObject(objectKey string, reader io.Reader, objectSize int64, contentType string, _persistance bool) (string, error) { _, err := s.client.Object.Put(context.Background(), objectKey, reader, &cos.ObjectPutOptions{ ObjectPutHeaderOptions: &cos.ObjectPutHeaderOptions{ ContentType: contentType, ContentLength: objectSize, }, }) if err != nil { return "", err } return s.domain + objectKey, nil } func (s *cosCreateServant) PersistObject(_objectKey string) error { // empty return nil } func (s *cosCreateTempDirServant) PutObject(objectKey string, reader io.Reader, objectSize int64, contentType string, persistance bool) (string, error) { objectName := objectKey if !persistance { objectName = s.tempDir + objectKey } _, err := s.client.Object.Put(context.Background(), objectName, reader, &cos.ObjectPutOptions{ ObjectPutHeaderOptions: &cos.ObjectPutHeaderOptions{ ContentType: contentType, ContentLength: objectSize, }, }) if err != nil { return "", err } return s.domain + objectKey, nil } func (s *cosCreateTempDirServant) PersistObject(objectKey string) error { exsit, err := s.client.Object.IsExist(context.Background(), objectKey) if err != nil { return err } if exsit { logrus.Debugf("object exist so do nothing objectKey: %s", objectKey) return nil } _, _, err = s.client.Object.Copy(context.Background(), objectKey, s.bucketUrl+s.tempDir+objectKey, nil) if err != nil { return err } _, err = s.client.Object.Delete(context.Background(), s.tempDir+objectKey, nil) return err } func (s *cosServant) DeleteObject(objectKey string) error { _, err := s.client.Object.Delete(context.Background(), objectKey) return err } func (s *cosServant) DeleteObjects(objectKeys []string) error { obs := []cos.Object{} for _, v := range objectKeys { obs = append(obs, cos.Object{Key: v}) } _, _, err := s.client.Object.DeleteMulti(context.Background(), &cos.ObjectDeleteMultiOptions{ Objects: obs, }) return err } func (s *cosServant) IsObjectExist(objectKey string) (bool, error) { return s.client.Object.IsExist(context.Background(), objectKey) } func (s *cosServant) SignURL(objectKey string, expiredInSec int64) (string, error) { signedURL, err := s.client.Object.GetPresignedURL(context.Background(), http.MethodGet, objectKey, conf.COSSetting.SecretID, conf.COSSetting.SecretKey, time.Second*time.Duration(expiredInSec), nil) if err != nil { logrus.Errorf("client.SignURL err: %v", err) return "", err } epath, err := url.PathUnescape(signedURL.Path) if err != nil { logrus.Errorf("url.PathUnescape err: %v", err) return "", err } signedURL.Path, signedURL.RawPath = epath, epath return signedURL.String(), nil } func (s *cosServant) ObjectURL(objetKey string) string { return s.domain + objetKey } func (s *cosServant) ObjectKey(objectUrl string) string { return strings.Replace(objectUrl, s.domain, "", -1) } func (s *cosServant) Name() string { return "COS" } func (s *cosServant) Version() *semver.Version { return semver.MustParse("v0.2.0") }