package cdsapi import ( "context" "fmt" "net/http" "net/url" "time" v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/credentials" "github.com/google/go-querystring/query" cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" ) type PresignedService struct { *Client } func (c *Client) Presigned() *PresignedService { return &PresignedService{ Client: c, } } const PresignedObjectDownloadByPathPath = "/v1/presigned/object/downloadByPath" type PresignedObjectDownloadByPath struct { UserID cdssdk.UserID `form:"userID" url:"userID" binding:"required"` PackageID cdssdk.PackageID `form:"packageID" url:"packageID" binding:"required"` Path string `form:"path" url:"path" binding:"required"` Offset int64 `form:"offset" url:"offset,omitempty"` Length *int64 `form:"length" url:"length,omitempty"` } func (c *PresignedService) ObjectDownloadByPath(req PresignedObjectDownloadByPath, expireIn int) (string, error) { return c.presign(req, PresignedObjectDownloadByPathPath, http.MethodGet, expireIn) } const PresignedObjectDownloadPath = "/v1/presigned/object/download" type PresignedObjectDownload struct { UserID cdssdk.UserID `form:"userID" url:"userID" binding:"required"` ObjectID cdssdk.ObjectID `form:"objectID" url:"objectID" binding:"required"` Offset int64 `form:"offset" url:"offset,omitempty"` Length *int64 `form:"length" url:"length,omitempty"` } func (c *PresignedService) ObjectDownload(req PresignedObjectDownload, expireIn int) (string, error) { return c.presign(req, PresignedObjectDownloadPath, http.MethodGet, expireIn) } const PresignedObjectUploadPath = "/v1/presigned/object/upload" type PresignedObjectUpload struct { UserID cdssdk.UserID `form:"userID" binding:"required" url:"userID"` PackageID cdssdk.PackageID `form:"packageID" binding:"required" url:"packageID"` Path string `form:"path" binding:"required" url:"path"` Affinity cdssdk.StorageID `form:"affinity" url:"affinity,omitempty"` LoadTo []cdssdk.StorageID `form:"loadTo" url:"loadTo,omitempty"` LoadToPath []string `form:"loadToPath" url:"loadToPath,omitempty"` } type PresignedObjectUploadResp struct { Object cdssdk.Object `json:"object"` } func (c *PresignedService) ObjectUpload(req PresignedObjectUpload, expireIn int) (string, error) { return c.presign(req, PresignedObjectUploadPath, http.MethodPost, expireIn) } const PresignedObjectNewMultipartUploadPath = "/v1/presigned/object/newMultipartUpload" type PresignedObjectNewMultipartUpload struct { UserID cdssdk.UserID `form:"userID" binding:"required" url:"userID"` PackageID cdssdk.PackageID `form:"packageID" binding:"required" url:"packageID"` Path string `form:"path" binding:"required" url:"path"` } type PresignedObjectNewMultipartUploadResp struct { Object cdssdk.Object `json:"object"` } func (c *PresignedService) ObjectNewMultipartUpload(req PresignedObjectNewMultipartUpload, expireIn int) (string, error) { return c.presign(req, PresignedObjectNewMultipartUploadPath, http.MethodPost, expireIn) } const PresignedObjectUploadPartPath = "/v1/presigned/object/uploadPart" type PresignedObjectUploadPart struct { UserID cdssdk.UserID `form:"userID" binding:"required" url:"userID"` ObjectID cdssdk.ObjectID `form:"objectID" binding:"required" url:"objectID"` Index int `form:"index" binding:"required" url:"index"` } type PresignedUploadPartResp struct{} func (c *PresignedService) ObjectUploadPart(req PresignedObjectUploadPart, expireIn int) (string, error) { return c.presign(req, PresignedObjectUploadPartPath, http.MethodPost, expireIn) } const PresignedObjectCompleteMultipartUploadPath = "/v1/presigned/object/completeMultipartUpload" type PresignedObjectCompleteMultipartUpload struct { UserID cdssdk.UserID `form:"userID" binding:"required" url:"userID"` ObjectID cdssdk.ObjectID `form:"objectID" binding:"required" url:"objectID"` Indexes []int `form:"indexes" binding:"required" url:"indexes"` } type PresignedObjectCompleteMultipartUploadResp struct { Object cdssdk.Object `json:"object"` } func (c *PresignedService) ObjectCompleteMultipartUpload(req PresignedObjectCompleteMultipartUpload, expireIn int) (string, error) { return c.presign(req, PresignedObjectCompleteMultipartUploadPath, http.MethodPost, expireIn) } func (c *PresignedService) presign(req any, path string, method string, expireIn int) (string, error) { u, err := url.Parse(c.cfg.URL) if err != nil { return "", err } u = u.JoinPath(path) us, err := query.Values(req) if err != nil { return "", err } us.Add("X-Expires", fmt.Sprintf("%v", expireIn)) u.RawQuery = us.Encode() prod := credentials.NewStaticCredentialsProvider(c.cfg.AccessKey, c.cfg.SecretKey, "") cred, err := prod.Retrieve(context.TODO()) if err != nil { return "", err } r, err := http.NewRequest(method, u.String(), nil) if err != nil { return "", err } signer := v4.NewSigner() signedURL, _, err := signer.PresignHTTP(context.Background(), cred, r, "", AuthService, AuthRegion, time.Now()) return signedURL, err }