package storage import ( "context" "errors" "fmt" "net/http" "net/url" "strings" "time" "github.com/tencentyun/cos-go-sdk-v5" ) var _ ObjectStorage = (*storageCos)(nil) type storageCos struct { client *cos.Client host string accessKey string accessSecret string bucket string } func newCosStorage(host, accessKey, accessSecret string) (ObjectStorage, error) { parts := strings.Split(host, ".") if len(parts) != 5 { return nil, errors.New("invalid cos host") } parts = strings.Split(parts[0], "-") if len(parts) != 2 { return nil, errors.New("invalid cos host") } bucketName := parts[0] u, err := url.Parse("https://" + host) if err != nil { return nil, err } client := cos.NewClient(&cos.BaseURL{BucketURL: u}, &http.Client{ Transport: &cos.AuthorizationTransport{ SecretID: accessKey, SecretKey: accessSecret, }, }) return &storageCos{ client: client, host: host, accessKey: accessKey, accessSecret: accessSecret, bucket: bucketName, }, nil } // PresignedPutObject implements ObjectStorage func (c *storageCos) PresignedPutObject(ctx context.Context, objectName string, expires time.Duration) (u *url.URL, err error) { return c.client.Object.GetPresignedURL(ctx, "PUT", objectName, c.accessKey, c.accessSecret, expires, nil) } // PresignedGetObject implements ObjectStorage func (c *storageCos) PresignedGetObject(ctx context.Context, objectName string, expires time.Duration) (u *url.URL, err error) { return c.client.Object.GetPresignedURL(ctx, "GET", objectName, c.accessKey, c.accessSecret, expires, nil) } // MoveObject implements ObjectStorage func (c *storageCos) MoveObject(ctx context.Context, src string, dst string) error { srcURL := fmt.Sprintf("%s/%s", c.host, src) if _, _, err := c.client.Object.Copy(ctx, dst, srcURL, nil); err != nil { return fmt.Errorf("copy object failed while move object: %w", err) } if _, err := c.client.Object.Delete(ctx, src, nil); err != nil { return fmt.Errorf("delete object failed while move object: %w", err) } return nil } // ObjectExists implements ObjectStorage func (c *storageCos) ObjectExists(ctx context.Context, objectName string) (bool, error) { return c.client.Object.IsExist(ctx, objectName) }